首页 > 解决方案 > useEffect 仅更新特定密钥更新

问题描述

我有一个场景,我们的应用程序有多个位于componentDidUpdate. 在每个函数中,他们都会检查其特定数据是否已更新。例如:

componentDidUpdate(prevProps) {
 this.handleFoo(prevProps)
 this.handleMoreFoo(prevProps)
}

handleFoo(prevProps){
  if(this.props.foo != prevProps.foo){
    //Do Something
 }
}

handleMoreFoo(prevProps){
  if(this.props.moreFoo != prevProps.moreFoo){
    //Do Something
 }
}

我一直在看useEffect钩子,想知道我是否可以在每个函数中删除初始检查并使用[]inuseEffect并且仅在它们的特定键更新如下时才调用其中一个函数:

useEffect(() => {
   if(fooKey){ handleFoo() }
   if(moreFoo) { handleMoreFoo() }
 }, [fooKey, moreFooKey])

这可能吗?这是可取的吗?

标签: reactjsreact-reduxreact-hooksuse-effect

解决方案


以下是您如何使用功能组件中的钩子来完成以前的工作。

我会根据Make React useEffect hook not run on initial rendercomponentDidUpdate()的答案定义一个自定义钩子来模仿:

function useUpdate (effect, deps) {
  const firstUpdate = useRef(true);
  const update = useCallback(() => {
    if (firstUpdate.current) {
      firstUpdate.current = false;
    } else {
      return effect();
    }
  }, [firstUpdate, effect]);

  useLayoutEffect(update, deps);
}

...

useUpdate(handleFoo, [fooKey]);
useUpdate(handleMoreFoo, [moreFooKey]);

useLayoutEffect()确保handleX()回调在每次渲染的同一阶段被调用,就像类比方法componentDidMount()componentDidUpdate()生命周期方法一样。如果您不关心调用它们的确切阶段,则可以替换useLayoutEffect()useEffect().

自定义钩子的其余部分确保它handleX()在初始渲染后跳过调用回调。如果您的handleX()回调可以在初始渲染后调用,那么您可以useEffect()直接在您的功能组件中调用,而不是这个useUpdate()自定义钩子。


推荐阅读