搜索

首页  >  问答  >  正文

状态设置器的react-hooks/exhaustive-deps警告有什么意义?

<p>我正在使用 React 构建分页。</p> <p>该应用程序使用状态管理分页和搜索。我想在搜索词更改时将分页重置为第 1 页。</p> <pre class="brush:php;toolbar:false;">// Simplified example function useSearchTerm() { return React.useState(""); } function usePage() { return React.useState(1); } function MyComponent(){ const [searchTerm, setSearchTerm] = useSearchTerm() const [page, setPage] = usePage(); useEffect(() => { setPage(1); }, [searchTerm]); // <-- Here is the ESLint warning }</pre> <p>这给我带来了 ESLint 警告 <code>React Hook useEffect 缺少依赖项:“setPage”。要么包含它,要么删除 useEffect 挂钩上的依赖项 array.eslintreact-hooks/exhaustive-deps。</p> <p>但是,当然,如果我在依赖项中包含 setPage,则每次渲染时都会调用该效果。</p> <p>我在这个用例上做错了什么吗?</p>
P粉465287592P粉465287592449 天前599

全部回复(1)我来回复

  • P粉156983446

    P粉1569834462023-09-02 00:17:20

    这个中间函数似乎是问题所在:

    function usePage() {
      return React.useState(1);
    }

    useState 返回的状态设置函数本身不会在每次渲染时重新创建,但通过此外部函数调用它似乎会破坏这一点。这导致依赖项发生变化,如 useEffect 依赖项数组所观察到的。

    如果您不需要这个 usePage 函数(在示例中您不需要,但在更大的上下文中可能存在有意义的情况),那么只需将其完全删除并使用直接useState

    const [page, setPage] = useState("");

    通常,人们无论如何都不想在函数内调用钩子,因为它可以快速且轻松地导致违反必须在每次渲染上一致且以相同顺序调用钩子的规则。因此,最好将钩子调用保留在组件本身的主体中(以及组件逻辑的早期)。

    有时,在某些情况下,您确实希望自定义函数充当 useEffect 中的依赖项。由于声明的函数在每次渲染时都会重新声明,因此您会遇到上面遇到的问题。为了解决这个问题,您可以将该函数包装在 useCallback 挂钩中,该挂钩本身也有一个依赖项数组,与 useEffect 非常相似。这个钩子的目的是创建自定义函数,React 可以将这些函数跨渲染缓存为单个函数实例(除非依赖项发生变化)。例如:

    const myCustomFunction = useCallback(args => {
      // use function args, etc.
    }, [someDependencies]);

    回复
    0
  • 取消回复