首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >useCallBack react-hooks/exhaustive deps警告

useCallBack react-hooks/exhaustive deps警告
EN

Stack Overflow用户
提问于 2021-01-10 08:24:33
回答 2查看 1.5K关注 0票数 2

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

代码语言:javascript
复制
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状态,它告诉我我的字段是否有效,我想让它“监听”注册函数中的每个变化。运行此命令后,我收到以下警告:

代码语言:javascript
复制
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

我的代码到底出了什么问题?我应该改变什么?为什么?谢谢!

EN

回答 2

Stack Overflow用户

发布于 2021-01-10 08:51:56

因为您没有将checkFieldsOK包装在useCallback中,所以它没有被注释,这意味着在每次渲染时都会重新创建它。因为您的useEffect具有checkFieldsOK作为依赖项,所以该效果也将运行每个渲染。

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

代码语言:javascript
复制
useEffect(() => {
    const checkFieldsOK = () => {
        return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
    }

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

但这意味着它只能在挂载时运行(因为依赖关系数组是空的),所以更好的方法是将checkFieldsOK函数包装在useCallback中,这样它就不会在每次重新渲染时重新生成,并且只有当字段值更改时才会运行效果:

代码语言:javascript
复制
const checkFieldsOK = useCallback(() => {
    return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
}, [email, password, passwordRepeat]);

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

运行字段值changes

  • checkFieldsOK函数获取remade

  • useEffect并检查字段的有效性,根据需要更新状态
票数 0
EN

Stack Overflow用户

发布于 2021-01-10 09:01:44

首先,我会考虑将checkFieldsOK表达式移到useEffect之上。

然后问问自己,checkFieldsOK是在什么时候创建和调用的?

假设isEmailisValidPassword是在组件外部声明的函数,要修复linter问题,您需要用useCallback包装checkFieldsOK

代码语言:javascript
复制
const checkFieldsOK = useCallback(() => {
        return (
          isEmail(email) &&
          isValidPassword(password) &&
          passwordRepeat === password
        );
    }, [email, password, passwordRepeat])

这样,每当emailpasswordpasswordRepeat发生变化时,checkFieldsOK就会更新它的输入。

或者将checkFieldsOK移动到useEffect中并更新效果依存关系:

代码语言:javascript
复制
    useEffect(() => {

      const checkFieldsOK = () => {
        return (
          isEmail(email) && 
          isValidPassword(password) && 
          passwordRepeat === password
         );
    }
        if (checkFieldsOK()) {
            setFieldsOK(true);
        } else {
            setFieldsOK(false);
        }
    }, [email, password, passwordRepeat])

这样,只有当电子邮件、密码或passwordRepeat状态更改时,才会触发您的效果。

您可以进一步简化为:

代码语言:javascript
复制
    useEffect(() => {

      const fieldsOK = 
          isEmail(email) && 
          isValidPassword(password) && 
          passwordRepeat === password
        
       setFieldsOK(fieldsOK);

    }, [email, password, passwordRepeat])
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65648999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档