如何解决如何在Formik的“ onSubmit”函数中正确地“使用状态”?
我在Next.js应用程序中使用了Formik,但遇到了一个不确定如何解决的问题。我的提交Button
是接受showSpinner
道具的组件。如果为true,则->按钮被禁用,并显示按钮中的加载微调器。 showSpinner
的值取决于来自loading
钩子的useState
。这是相关代码:
export default function register() {
const [loading,setLoading] = useState(false)
return (
<>
<Layout>
<div className={styles.registerContainer}>
<div className={styles.registerFormContainer}>
<h1 className={styles.registerHeader}>Sign Up</h1>
<Formik
initialValues={{
email: '',password: '',passwordConfirm: '',acceptedTerms: false
}}
onSubmit={
(values,{ setSubmitting }) => {
console.log(loading)
// here loading == false as expected
setLoading(true)
console.log(loading)
// here loading == false even though i set it to true
initFirebase()
firebase.auth().createuserWithEmailAndPassword(values.email,values.password)
.then((res) => {
console.log('done!')
})
.catch(function (error) {
// Handle Errors here.
console.log(error)
})
.finally(() => {
console.log(loading)
//here loading == false too,even though I expected it to be true
setSubmitting(false)
setLoading(false)
})
}
}
>
<Form>
<FormikText label="Email:"
name="email"
type="email"
id="email" />
<FormikPassword label="Password:"
name="password"
id="password"
/>
<FormikPassword label="Confirm Password:"
name="passwordConfirm"
id="passwordCOnfirm"
/>
<FormikCheckBox
name="acceptedTerms"
id="acceptedTerms"
>
<span className={styles.checkBoxLabel}>
I agree to the <Link href="/terms" ><a className={styles.registerLink}>Terms of Service</a></Link> and <Link href="/privacy"><a className={styles.registerLink}>Privacy/Cookie Policy</a></Link>
</span>
</FormikCheckBox>
<div className={styles.buttonContainer}>
<Button type="submit" color="blue" showSpinner={loading}>Sign Up</Button>
</div>
</Form>
</Formik>
</div>
</div>
</Layout>
</>
)
}
即使我的Button
以某种方式正常工作(按预期方式显示了旋转框),在通过console.loging
函数调用的loading
的{{1}}值之后,我仍然注意到我期望onSubmit
是真的。是由于React批处理false
调用的方式吗?
我的问题是:
- 如何正确处理这种情况?
- 如果
useState
中的loading == false
,为什么我的console.logs
按预期工作?
解决方法
这是由于React批处理useState调用的方式造成的吗?
我这么认为,这就是Formik
提供isSubmitting
标志,尝试使用它而不是跟踪您自己的loading
状态的原因,我知道它适用于您当前的规格,但是您可以当该组件变得更复杂时会有一些问题
您的代码如下所示
export default function register() {
return (
<>
<Layout>
<div className={styles.registerContainer}>
<div className={styles.registerFormContainer}>
<h1 className={styles.registerHeader}>Sign Up</h1>
<Formik
initialValues={{
email: "",password: "",passwordConfirm: "",acceptedTerms: false,}}
onSubmit={async (values) => {
try {
initFirebase();
await firebase
.auth()
.createUserWithEmailAndPassword(
values.email,values.password
);
} catch (e) {
// Handle Errors here.
console.log(error);
}
}}
>
{({ isSubmitting }) => (
<Form>
<FormikText
label="Email:"
name="email"
type="email"
id="email"
/>
<FormikPassword
label="Password:"
name="password"
id="password"
/>
<FormikPassword
label="Confirm Password:"
name="passwordConfirm"
id="passwordCOnfirm"
/>
<FormikCheckbox name="acceptedTerms" id="acceptedTerms">
<span className={styles.checkboxLabel}>
I agree to the{" "}
<Link href="/terms">
<a className={styles.registerLink}>Terms of Service</a>
</Link>{" "}
and{" "}
<Link href="/privacy">
<a className={styles.registerLink}>
Privacy/Cookie Policy
</a>
</Link>
</span>
</FormikCheckbox>
<div className={styles.buttonContainer}>
<Button
type="submit"
color="blue"
showSpinner={isSubmitting}
>
Sign Up
</Button>
</div>
</Form>
)}
</Formik>
</div>
</div>
</Layout>
</>
);
}
拍摄版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。