[英]Formik State returns OLD NOT the RECENT or CURRENT values after Linking Event Listener is called
我正在嘗試在 REACT-NATIVE 中創建注冊流程。 過程是:填寫表單 > 驗證並提交表單 > 打開返回深層鏈接的 URL > 捕獲深層鏈接 > 使用表單值和深層鏈接參數注冊用戶
問題是當監聽器被調用時,我嘗試在其中使用 formik 表單值,它返回 Formik 的初始值,而不是更新的 CURRENT 值。
const formik = useFormik({
initialValues: {
username: '',
email: '',
password: ''
},
onSubmit: (values) => {
Linking.openURL(URL);
},
validationSchema: getValidation(), // Yup.object
});
useEffect(() => {
Linking.addEventListener('url', handleOpenUrl);
return () => {
Linking.removeListener('url', handleOpenUrl);
};
}, []);
const handleOpenUrl = (event) => {
var code = event.url.split('//')[1].split('/')[1];
if (code !== 'error) {
console.log(code , formik.values); // returns initialValue
// onRegister(formik.values, code )
}
};
我調用 formik.handleSubmit() 來驗證數據並調用 onSubmit
對於遇到相同或類似問題的任何人,這就是它發生的原因以及我為解決它所做的工作。
問題/原因:
事件監聽器只會在初始渲染時知道組件的 state。 因為當 state 更改時事件偵聽器不會更新,所以它們不會意識到發生的更改。 這是 React 的事件監聽器的問題,不僅僅是在 useFormik 中。
解決方案:
useRef鈎子,它可以訪問實時 state 值
代碼:
const formik = useFormik({
initialValues: {
username: '',
email: '',
}
onSubmit: (values) => {
Linking.openURL(URL_TO_OPEN);
},
validationScheme: someValidationScheme(), // Yup.object
});
// just like other hook, you need to put an initial value, use the same object used in useFormik
const formValueRef = useRef(initialValues);
// useRef.current - stores the CURRENT value you passed, and can be accessed anytime
const setFormValues = (values) => {
formValueRef.current = values;
formik.setValues(values);
};
useEffect(() => {
Linking.addEventListener('url', handleOpenUrl);
return () => {
Linking.removeListener('url', handleOpenUrl);
};
}, []);
const handleOpenUrl = (event) => {
var code = event.url.split('//');
if (code !== 'error) {
//this NOW RETURNS the CURRENT VALUE of formik that is passed to formValueRef.current
console.log(code, formValueRef.current.username, formValueRef.current.email);
}
}
我認為問題在於您在 useEffect 中注冊了沒有依賴關系的事件處理程序,因此處理程序是用舊的 state 記錄的。 我建議像這樣更新
useEffect(() => {
Linking.addEventListener('url', handleOpenUrl);
return () => {
Linking.removeListener('url', handleOpenUrl);
};
}, [formik.values]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.