useCallBack React-hooks/exhaustive-deps 警告

Nao*_*aor 5 reactjs react-hooks usecallback use-effect

这是我在 React js 中的代码的一部分:

export default function Registration() {
    const [email, setEmail] = useState(null);
    const [password, setPassword] = useState(null);
    const [passwordRepeat, setPasswordRepeat] = useState(null);
    const [isFieldsOK, setFieldsOK] = useState(false);

    useEffect(() => {
        if (checkFieldsOK()) {
            setFieldsOK(true);
        } else {
            setFieldsOK(false);
        }
    }, [checkFieldsOK])

    const checkFieldsOK = () => {
        return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
    }
}
Run Code Online (Sandbox Code Playgroud)

我有 isFieldsOK 状态,它告诉我我的字段是否有效,并且我希望它“侦听”注册功能中的每个更改。运行此命令后,我收到此警告:

The 'checkFieldsOK' function makes the dependencies of useEffect Hook (at line 34) change on every render. Move it inside the useEffect callback. Alternatively, wrap the definition of 'checkFieldsOK' in its own useCallback() Hook  react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)

我的代码到底有什么问题?我应该改变什么以及为什么?谢谢你!

Jay*_*444 0

因为您没有换行checkFieldsOKuseCallback所以它不会被记忆,这意味着它会在每次渲染时重新创建。因为你useEffectcheckFieldsOK一个依赖项,所以该效果也将在每次渲染时运行。

正如错误消息所述,第一个(我认为不正确)选项是将函数声明移动到内部,如下useEffect所示:

useEffect(() => {
    const checkFieldsOK = () => {
        return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
    }

    if (checkFieldsOK()) {
        setFieldsOK(true);
    } else {
        setFieldsOK(false);
    }
}, []);
Run Code Online (Sandbox Code Playgroud)

但这意味着它只会在挂载时运行(因为依赖项数组为空),因此更好的方法是将函数包装checkFieldsOK在 a 中useCallback,这样它就不会在每次重新渲染时都重新制作,并且效果仅在字段值更改时运行:

const checkFieldsOK = useCallback(() => {
    return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
}, [email, password, passwordRepeat]);
Run Code Online (Sandbox Code Playgroud)

在第二种useCallback方法中,它的行为如下:

  1. 字段值变化
  2. checkFieldsOK函数被重新设计
  3. useEffect运行并检查字段的验证,根据需要更新状态