如何在反应中处理自定义钩子的依赖项数组

wei*_*wei 29 reactjs react-hooks

我正在创建一个自定义钩子,并想定义一个可选参数,以便我可以在需要时传入额外的依赖项。我的代码如下所示:

import { useEffect } from 'react';

function useCustomHook(param1, extraDeps) {
  useEffect(() => {
    // do something with param1 here
  }, [param1, ...extraDeps])
}
Run Code Online (Sandbox Code Playgroud)

react-hooks/exhaustive-deps 发出警告说

React Hook useEffect 在其依赖数组中有一个 spread 元素。这意味着我们无法静态验证您是否传递了正确的依赖项

任何人都知道如何解决该警告?或者将 deps 数组传递给自定义钩子不是一个好习惯?

对于那些对为什么需要 extraDeps 感兴趣的人。这是一个例子:

const NewComponent = (props) => {
  [field1, setField1] = useState()
  [field2, setField2] = useState()

  // I only want this to be called when field1 change
  useCustomHook('.css-selector', [field1]);

  return <div>{field1}{field2}</div>;
}
Run Code Online (Sandbox Code Playgroud)

Dia*_*adt 16

我找到了此处提出的解决方案的有用替代方案。正如Reddit 主题中提到的,React 团队显然推荐了类似的内容:

// Pass the callback as a dependency
const useCustomHook = callback => {
  useEffect(() => { /* do something */ }, [callback])
};

// Then the user wraps the callback in `useMemo` to avoid running the effect too often
// Whenever the deps change, useMemo will ensure that the callback changes, which will cause effect to re-run
useCustomHook(
  useMemo(() => { /* do something */ }, [a, b, c])
);
Run Code Online (Sandbox Code Playgroud)

我已经使用了这种技术并且效果非常好。

  • 在这个例子中,“callback”变量名非常令人困惑。如果 `useCustomHook` 确实想要一个回调作为其参数,那么最好使用 `useCallback()` 而不是 `useMemo()`。如果参数是一个对象(例如原始示例中的“param1”),则“useMemo()”就可以了。 (2认同)

Ste*_*e L 5

我有一个类似的问题,我希望每当一些额外的依赖项发生更改时都会执行效果。
我没有设法提供这些额外的依赖项,而是通过向调用者提供我想要执行的回调并让他在需要时使用它来解决这个问题。

例子 :

// This hook uses extraDeps unknown by EsLint which causes a warning
const useCustomEffect = (knowDep, extraDeps) => {

  const doSomething = useCallback((knownDep) => {/**/}, [])
  
  useEffect(() => {
    doSomething(knownDep)
  }, [doSomething, knownDep, ...extraDeps]) // Here there is the warning
}

//Instead of this, we give the caller the callback
const useCustomEffect = (knownDep) => {

  const doSomething = useCallback((knownDep) => {/**/}, [])
  
  useEffect(() => {
    doSomething(knownDep)
  }, [doSomething, knownDep]) // no more warning

  return { doSomething }
}

// Use it like this
const { doSomething } = useCustomEffect(foo)
useEffect(doSomething, [bar, baz]) // now I can use my callback for any known dependency

Run Code Online (Sandbox Code Playgroud)

  • 这段代码对我来说没有多大意义,我不确定为什么它收到了这么多的赞成票。首先,在`useCustomEffect`中调用`useEffect`是不必要的,并且会导致组件挂载时运行两次效果。其次,“useCallback”的依赖项中缺少“knownDep”。第三,您不会对“useEffect”调用进行任何依赖项检查。 (5认同)