Как преобразовать компонент с функцией конструктора и реквизита в функциональный компонент с помощью хуков и реквизита - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь оптимизировать изображения в своем веб-приложении на go. Я пытаюсь изменить код, который работает как функция класса с конструктором , в функциональный компонент, который использует перехватчики .

Причина, по которой он мне нужен функциональным компонентом является то, что мне нужно пройти реквизит. Мне нужно, чтобы это было многоразовым. Мне нужно сделать это: если я могу сделать это в коде с конструктором, пожалуйста, дайте мне знать или укажите где-нибудь, это жизнеспособный вариант.

Мне нужно многократно использовать, чтобы я мог использовать его на всех моих элементах img, в этом отношении:

<img src={props.image} />

Я смог достичь этого только с помощью функционального компонента. Вот почему я пытаюсь сделать это функциональным компонентом. Чтобы решить конкретную проблему c, я не могу это сделать из-за этой функции конструктора.

Это рабочий код конструктора:

import React from "react";
import ReactDOM from "react-dom";

import TestImage from "./test-image.png";

export default class ImgOptimise extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      width: 0
    };
    this.imgRef = React.createRef();
  }

  componentDidMount() {
    const width = this.imgRef.current.clientWidth;
    this.setState({
      width
    });
  }

  render() {
    // Destructure props and state
    const { src, alt, options = {}, ext = "jpg" } = this.props;
    const { width } = this.state;

    // Create an empty query string
    let queryString = "";

    // If width is specified, otherwise use auto-detected width
    options["w"] = options["w"] || width;

    // Loop through option object and build queryString
    Object.keys(options).map((option, i) => {
      return (queryString += `${i < 1 ? "?" : "&"}${option}=${
        options[option]
      }`);
    });

    return (
      <figure ref={this.imgRef}>
        {// If the container width has been set, display the image else null
        width > 0 ? (
          <>
            <img src={TestImage} alt="test" />
          </>
        ) : null}
      </figure>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<ImgOptimise />, rootElement);


Это мой код для перевода это к функциональному компоненту с помощью крючков

https://codesandbox.io/live/Wr7V4

Полный код ниже:

import React, { useState, useEffect } from "react";
import TestImage from "./test-image.png";

const ImgOptimise = props => {
  // Destructure props and state
  const { src, alt, options = {}, ext = "jpg" } = useEffect(0);
  const [width] = useState(0);


  const imgRef = React.createRef();
  useEffect(() => {
    const width = imgRef.current.clientWidth;
  }, []);

  // Create an empty query string
  let queryString = "";
  // If width is specified, otherwise use auto-detected width
  options["w"] = options["w"] || width;
  // Loop through option object and build queryString
  Object.keys(options).map((option, i) => {
    return (queryString += `${i < 1 ? "?" : "&"}${option}=${options[option]}`);
  });
  return (
    // If the container width has been set, display the image else null
    <figure ref={imgRef}>
      {// If the container width has been set, display the image else null
      width > 0 ? (
        <>
          <img src={TestImage} />
        </>
      ) : null}
    </figure>
  );
};
export default ImgOptimise;

const rootElement = document.getElementById("root");
ReactDOM.render(<ImgOptimise />, rootElement);

ОШИБКА: TypeError: Cannot destructure property 'src' of 'Object(...)(...)' as it is undefined.

что-то с этим делать, я не уверен, как правильно его деструктурировать:

//Constructor const { src, alt, options = {}, ext = "jpg" } = this.props;

//Hooks const { src, alt, options = {}, ext = "jpg" } = useEffect(0);

Я также не уверен, правильно ли я перевел это

    this.imgRef = React.createRef();
  }

  componentDidMount() {
    const width = this.imgRef.current.clientWidth;
    this.setState({
      width
    });
  }

на это:

 const [width] = useState(0);
  // const [nameState , setNameState] = useState(props);
  const imgRef = React.createRef();
  useEffect(() => {
    const width = imgRef.current.clientWidth;
  }, []);

Любая справка по изменению этого с компонента класса на функциональный компонент будет принята с благодарностью .

ОБНОВЛЕНИЕ

Оказывается, моя была ошибкой ладьи ie. Я упустил из виду this

Несмотря на то, что моя проблема была решена, я оставлю вопрос открытым, так как будет интересно увидеть, как он превратился в функциональный компонент, потому что, ну почему бы и нет?

1 Ответ

1 голос
/ 18 февраля 2020

Если это ваши реквизиты, вам просто нужно их деструктурировать, а не применять useEffect ().

const { src, alt, options = {}, ext = "jpg" } = props;

Для вашего состояния необходимо определить функцию вместе с переменной состояния.

const [width, setWidth] = useState(0);

Затем вызовите эту функцию для обновления width.

setWidth(imgRef.current.clientWidth);

Дополнительную информацию можно найти, выполнив поиск, например, https://duckduckgo.com/?q=how+to+convert+react+component+to+hooks&ia=web, что приведет к некоторым хорошим статьям как https://alligator.io/react/converting-to-a-hook/

...