首页 > 解决方案 > 将 componentWillReceiveProps 函数转换为反应钩子

问题描述

嘿,所有人都给出了一个基本的反应组件,它具有componentWillReceiveProps. 我想将其转换为使用反应钩子。现在我已经在这里查看了这个问题,虽然答案很简单,但我觉得我好像错过了理解某些东西。例如:

export class Example extends React.Component {
  constructor(props) {
    super(props);
  }

  componentWillReceiveProps(nextProps) {
    console.log('HELLO WORLD') // Note this isn't called on initial render
    if (nextProps.match.params.id != this.props.match.params.id) {
      console.log('testing....')
    }
  }

  render() {
    return (
      <div>Cool</div>
    );
  }
}

我从上面的例子中知道,除非 nextProps 没有改变,否则我们不会进入 if 语句。现在将上面的转换为函数组件是这样的:

export const Example = ({ ...props }) => {
  useEffect(() => {
    console.log('TESTING')
  }, [props.match.params.id])

  return (
    <div>Cool</div>
  )
}

我还准备了我所见内容的简短录音 gif。https://recordit.co/hPuwGey6WM

标签: reactjsreact-hooks

解决方案


不幸的是,useEffect它被设计为在第一次渲染时运行,并且每次它的依赖关系发生变化。

为了避免在第一次渲染时运行,您必须编写自己的小自定义钩子。

const useComponentWillReceiveProps = (callback, dependencies) => {
  const [firstRender, setFirstRender] = useState(true);

  useEffect(() => {
     if(firstRender) {
        setFirstRender(false);
        return;
     }
     callback();
  }, dependencies);
}

或者,您也可以使用 refs 来避免初始重新渲染,例如:

const useComponentWillReceiveProps = (callback, dependencies) => {
   const firstRender = useRef(true);

  useEffect(() => {
     if(firstRender.current) {
        firstRender.current = false;
        return;
     }
     callback();
  }, dependencies);
}

推荐阅读