Reactjs 使用回调响应挂钩/详尽的deps警告

Reactjs 使用回调响应挂钩/详尽的deps警告,reactjs,react-hooks,use-effect,usecallback,Reactjs,React Hooks,Use Effect,Usecallback,这是我在React js中代码的一部分: export default function Registration() { const [email, setEmail] = useState(null); const [password, setPassword] = useState(null); const [passwordRepeat, setPasswordRepeat] = useState(null); const [isFieldsOK, set

这是我在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);
    }
}
我有一个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
我的代码到底出了什么问题?我应该改变什么?为什么?
谢谢大家!

因为您没有在
useCallback
中包装
checkFieldsOK
,所以它不会被记忆,这意味着它会在每次渲染时重新创建。而且由于您的
useffect
具有
checkFieldsOK
作为依赖项,因此该效果也将运行每个渲染

正如错误消息所说,第一个(我认为是错误的)选项是在
useffect
中移动函数声明,如下所示:

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

    if (checkFieldsOK()) {
        setFieldsOK(true);
    } else {
        setFieldsOK(false);
    }
}, []);
但这意味着它将只在装载时运行(因为依赖项数组是空的),因此更好的方法是将
checkFieldsOK
函数包装在
useCallback
中,这样它就不会每次重新渲染时都重新生成,并且只在字段值更改时运行效果:

const checkFieldsOK = useCallback(() => {
    return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
}, [email, password, passwordRepeat]);
在第二种
useCallback
方法中,其行为如下:

  • 字段值更改
  • checkFieldsOK
    函数重新生成
  • useffect
    运行并检查字段的有效性,根据需要更新状态

  • 首先考虑移动<代码>校验字段> /COD>表达式>代码>使用效果< /代码> ./P> 然后问问自己,当创建了

    checkFieldsOK
    时,调用了什么

    假设
    isEmail
    isValidPassword
    是在组件外部声明的函数,要解决linter问题,您需要使用
    useCallback
    包装
    checkFieldsOK

    const checkFieldsOK = useCallback(() => {
            return (
              isEmail(email) &&
              isValidPassword(password) &&
              passwordRepeat === password
            );
        }, [email, password, passwordRepeat])
    
    
    这样,每当
    电子邮件
    密码
    密码重复
    发生更改时,
    检查字段SOK将更新其输入

    或者将
    checkFieldsOK
    移动到useffect并更新效果依赖项:

        useEffect(() => {
    
          const checkFieldsOK = () => {
            return (
              isEmail(email) && 
              isValidPassword(password) && 
              passwordRepeat === password
             );
        }
            if (checkFieldsOK()) {
                setFieldsOK(true);
            } else {
                setFieldsOK(false);
            }
        }, [email, password, passwordRepeat])
    
    
    这样,只有当电子邮件、密码或passwordRepeat状态发生更改时,才会触发您的效果

    您可以进一步简化为:

        useEffect(() => {
    
          const fieldsOK = 
              isEmail(email) && 
              isValidPassword(password) && 
              passwordRepeat === password
            
           setFieldsOK(fieldsOK);
    
        }, [email, password, passwordRepeat])
    

    如果您使用的是eslint,请签出此链接。