首页 > 解决方案 > React hooks:只监听一个状态变化但依赖其他几个状态来更新一个新状态?

问题描述

我对 React 和函数式编程很陌生。我想构建一个父组件,它基本上告诉子组件应该呈现什么:

const Parent = (props) => {
  // blablabla...
  useEffect(() => {
    // blablabla...
    let newSomeOtherState = doSomething(stateThatFrequentlyChange, stateThatSeldomChange)
    setSomeOtherState(newSomeOtherState)
  }, [stateThatFrequentlyChange, stateThatSeldomChange])

  return <Child data={someOtherState} />
}

问题是我只希望父组件监听stateThatSeldomChange然后someOtherState根据当前的stateThatFrequentlyChange.

如果我删除stateThatFrequentlyChange,React 会抱怨React Hooks useEffect has missing dependencies...

我应该如何解决这个警告?

标签: reactjsreact-hooks

解决方案


在这种情况下,常见的模式是检查正确的参数是否触发了useEffect,这可以通过通过引用将当前值与前一个值进行比较来实现:

const usePrevious = (arg, compareFn) => {
  const prevState = useRef();

  // Keep ref updated
  useEffect(() => {
    if (compareFn(prevStateSeldom.current, arg)) {
      prevState.current = arg;
    }
  }, [arg]);

  return prevStateSeldom.current;
};

const Parent = (props) => {
  const prevState = usePrevious(stateThatSeldomChange, Object.is);

  useEffect(() => {
    if (prevState !== stateThatSeldomChange) {
      setSomeOtherState(stateThatFrequentlyChange);
    }
  }, [stateThatFrequentlyChange, stateThatSeldomChange]);

  return <Child data={someOtherState} />;
};

此示例遵循常见的良好实践和已知假设(有关更多信息,请参见useEffect案例):

  • 每个人都useEffect应该有一个单一的责任。
  • 钩子按顺​​序调用,因此您应该将逻辑提取到自定义钩子中,以便将变量公开到范围内。

这个逻辑一般是通过usePrevious钩子实现的,你可以研究一下收据。


推荐阅读