Reactjs 使用回调响应挂钩/详尽的deps警告
这是我在React js中代码的一部分: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
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,请签出此链接。