javascript - 如何在第一次运行时跳过运行 useEffect 是严格模式?
问题描述
我有一个自定义钩子,当我需要useEffect
在第一次调用时跳过该函数的运行时使用它。这在非严格模式下就像一个魅力。
hooks/useEffectSkipFirst.js
import { useCallback, useEffect, useRef } from 'react';
export default (fn, deps) => {
const isFirstRun = useRef(true);
const execFunc = useCallback(fn, deps);
useEffect(() => {
if (isFirstRun.current) {
isFirstRun.current = false;
return;
}
execFunc();
}, [execFunc])
};
用法:
import useEffectSkipFirst from 'hooks/useEffectSkipFirst';
useEffectSkipFirst(() => {
// fetch new user by ID
}, [selectedUser.id])
显然,这个钩子在严格模式下的工作方式完全不同,它会在第一次调用时执行一个函数,因为useEffect
钩子会被调用两次。它会被调用两次的原因是它的依赖是一个从useState
(或 react-redux's useSelector
)返回的变量,它在严格模式下被调用两次。因此,它会在第一次运行时进行 API 调用,而在用户更改之前不应调用。
我可以解决这个问题的唯一方法是听NODE_ENV
变量,在开发的情况下,我会阻止函数的执行直到第 3 次调用,而在其他环境的情况下阻塞直到第 2 次调用。不幸的是,这对我来说听起来像是一个糟糕的解决方案。
有没有更好的方法来编写在两种模式下都可以使用的自定义钩子?请记住,编写一个不会引发任何eslint-plugin-react-hook
警告的钩子很重要。
编辑:我的史诗般的脸。在非严格模式下一切都对我有用并且在严格模式下不起作用的原因是我的所有路线都是通过Private.js
组件呈现的,该组件检查我是否已经有一个用户在商店(登录)或没有。如果我没有用户,它将进行 API 调用。因为我在渲染函数中进行检查(错误地在该检查中有副作用)并且在严格模式下调用了两次渲染,所以我实际上进行了 2 次 API 调用(错误)。这也意味着我的 Redux 存储被更新了两次,从而触发了我的 useEffect 两次,它将该变量作为依赖项。我一直在错误的地方寻找错误。我为浪费您的时间而道歉。
解决方案
推荐阅读
- c++ - Command CodeSign 出现问题失败,退出代码为非零,还给了我签名身份:“-”
- jquery - 如何使用 windows.print 让两个按钮打印不同的部分?
- flutter - 为什么在使用带有 selectedItemBuilder 和提示的 DropdownButton 时会出现类型错误?
- c# - 如果类将对象引用作为其值,为什么“new”关键字不覆盖它们?
- laravel - 检查更新表单中的多个复选框
- paypal - 如何忽略 codeigniter 中的 PayPal 描述框?
- python - Pytorch 1.6.0 - RuntimeError:CUDA 错误:设备端断言触发的位置(预测==标签)
- java - 在java中,如何循环遍历单词中的每个字符,然后确定该字符获得的点并继续为单词添加点
- python - Tkinter 标签未跨类更新(另一个)
- windows - 以编程方式更改 Windows 笔记本电脑的刷新率