React 在 useEffect 中重写 componentWillReceiveProps

IT技术 reactjs react-hooks
2021-04-09 05:48:47

所以我正在重新编写一个带有钩子的组件,我遇到了一个有趣的挑战,我需要模仿一些componentWillReceiveProps带有useEffect钩子的旧行为

我的旧代码如下:

componentWillReceiveProps(nextProps: Props) {

  const prevLateVal = get(`lateMinutes[${bookingId}].value`, this.props);
  const nextLateVal = get(`lateMinutes[${bookingId}].value`, nextProps); //see here, 
//we use next props

  if (typeof nextLateVal !== 'undefined' && prevLateVal !== nextLateVal) {
    client.connect(bookingId, nextLateVal === null ? 0 : nextLateVal);

  }
}

你看,我正在启动一个const基于 nextProps,然后在if语句中我基于 nextVal做一些检查,现在,我知道我们可以指定第二个参数useEffect来运行它,只有当props改变时,但那些呢检查,我怎样才能实现类似的东西nextProps

4个回答

您可以创建自定义钩子:

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.prevLateVal = value;
  });
  return ref.prevLateVal;
}

并将其用于 useEffect()

const Component = (props) => {
    const currentLateValue = get(`lateMinutes[${bookingId}].value`, props)
    const prevLateVal = usePrevious(currentLateValue);
    useEffect(() => {
        if(prevLateVal !== currentLateValue) {
         // process here
        }
    }, [currentLateValue]) // This will be executed only if currentLateValue changes.
}
天才!谢谢!
2021-06-13 05:48:47

您可以使用useRef来保存上一个props,并useEffect在props更改时使用它来运行,如下所示:

function MyComponent(props) {

  const prevProps = useRef(props);

  useEffect(() => {
    const prevLateVal = get(`lateMinutes[${bookingId}].value`, prevProps.current);
    const nextLateVal = get(`lateMinutes[${bookingId}].value`, props);

    if (typeof nextLateVal !== 'undefined' && prevLateVal !== nextLateVal) {
      client.connect(bookingId, nextLateVal === null ? 0 : nextLateVal);
    }    

    prevProps.current = props;
  }, [props, bookingId]);

  return (<div>...</div>)
}
在组件内部不可变,但它的父亲可能会改变属性而不是引用
2021-06-02 05:48:47
好吧,道具是不可变的,不是吗?
2021-06-03 05:48:47
它将在每次渲染时运行,而不是在道具更改时运行,同时考虑到逻辑,它应该只在特定对象属性更改时运行
2021-06-06 05:48:47
我在 useEffect 的第二个参数中添加了 props
2021-06-14 05:48:47
它仍然有问题,因为您假设道具参考正在发生变化
2021-06-22 05:48:47

使用当前的逻辑,您只想在lateMinutes[${bookingId}].value更改时触发副作用

const Component = props => {
  useEffect(() => {
    console.log('prop lateMinutes changed');
    // ...
  }, [props[`lateMinutes[${bookingId}].value`]);
  return ...
};

您不需要钩子来处理预渲染生命周期。只需在返回 JSX 之前将东西放在函数组件中,因为函数本身相当于基于类的组件的渲染方法。