![](/img/trans.png)
[英]React useEffect hook with warning react-hooks/exhaustive-deps
[英]useCallBack react-hooks/exhaustive-deps warning
這是我在 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 state 它告訴我我的字段是否有效,我希望它“監聽”注冊 function 中的每一個更改。 運行此程序后,我收到此警告:
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
我的代碼到底有什么問題? 我應該改變什么,為什么? 謝謝!
因為您沒有將checkFieldsOK
包裝在useCallback
中,所以它沒有被記憶,這意味着它會在每次渲染時重新創建。 並且因為您的useEffect
具有checkFieldsOK
作為依賴項,所以該效果也將運行每個渲染。
正如錯誤消息所說,第一個(我認為不正確)選項是將 function 聲明移動到useEffect
中,如下所示:
useEffect(() => {
const checkFieldsOK = () => {
return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
}
if (checkFieldsOK()) {
setFieldsOK(true);
} else {
setFieldsOK(false);
}
}, []);
但這意味着它只會在掛載時運行(因為依賴數組為空),因此更好的方法是將checkFieldsOK
function 包裝在useCallback
中,因此不會在每次重新渲染時重新制作,並且效果僅在字段時運行值變化:
const checkFieldsOK = useCallback(() => {
return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
}, [email, password, passwordRepeat]);
在第二種useCallback
方法中,它的行為如下:
checkFieldsOK
function 重新制作useEffect
運行並檢查字段的驗證,根據需要更新 state首先,我會考慮將checkFieldsOK
表達式移到useEffect
上方。
然后問自己, checkFieldsOK
是什么時候創建的,調用的?
假設isEmail
和isValidPassword
是在組件外部聲明的函數,要解決 linter 問題,您需要使用useCallback
checkFieldsOK
const checkFieldsOK = useCallback(() => {
return (
isEmail(email) &&
isValidPassword(password) &&
passwordRepeat === password
);
}, [email, password, passwordRepeat])
這樣,只要email
、 password
或passwordRepeat
發生變化, checkFieldsOK
就會更新它的輸入。
或將checkFieldsOK
移至 useEffect 並更新效果依賴項:
useEffect(() => {
const checkFieldsOK = () => {
return (
isEmail(email) &&
isValidPassword(password) &&
passwordRepeat === password
);
}
if (checkFieldsOK()) {
setFieldsOK(true);
} else {
setFieldsOK(false);
}
}, [email, password, passwordRepeat])
這樣,只有在 email、密碼或密碼重復 state 更改時才會觸發您的效果。
您可以進一步簡化為:
useEffect(() => {
const fieldsOK =
isEmail(email) &&
isValidPassword(password) &&
passwordRepeat === password
setFieldsOK(fieldsOK);
}, [email, password, passwordRepeat])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.