如何使用 hooks 和 props 将具有构造函数和 props 的组件转换为功能组件

How do I convert a component with a constructor function and props, to a functional component using hooks and props

我正在尝试在旅途中优化我的网络应用程序中的图像。我正在尝试 将作为带有构造函数 的 class 函数工作的代码修改为使用 hooks 的 功能组件。

我需要它成为功能组件的原因是我需要传递道具。我需要它是可重复使用的。我需要这样做:如果我可以在代码中使用构造函数执行此操作,请告诉我或指出某个地方,这是一个可行的选择。

我需要可重复使用,以便我可以在我所有的 img 元素上使用它,在这方面:

<img src={props.image} />

我只能通过功能组件实现这一点。这就是为什么我试图将它变成一个功能组件。为了解决一个特定的问题,我因为那个构造函数而无法做到。

这是有效的构造函数代码:

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;
  }, []);

任何将其从 class 组件更改为功能组件的帮助将不胜感激。

更新

原来我是一个菜鸟错误。我忽略了this

虽然我的问题已经解决了,但我还是将问题悬而未决,因为看到它变成一个功能组件会很有趣,因为,为什么不呢?

如果这些是你的道具,你只需要解构它们,而不是应用 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 , which results in some good articles like https://alligator.io/react/converting-to-a-hook/