Javascript 如何';useState';正确使用Formik';onSubmit';功能?
我在Next.js应用程序中使用了Formik,遇到了一个不确定如何解决的问题。我的提交Javascript 如何';useState';正确使用Formik';onSubmit';功能?,javascript,reactjs,next.js,formik,Javascript,Reactjs,Next.js,Formik,我在Next.js应用程序中使用了Formik,遇到了一个不确定如何解决的问题。我的提交按钮是一个接受showSpinner道具的组件。如果为真->按钮被禁用,并在按钮中显示加载微调器showSpinner值取决于来自useStatehook的loading。以下是相关代码: export default function register() { const [loading, setLoading] = useState(false) return ( <> &
按钮
是一个接受showSpinner
道具的组件。如果为真->按钮被禁用,并在按钮中显示加载微调器showSpinner
值取决于来自useState
hook的loading
。以下是相关代码:
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>
</>
)
}
导出默认函数寄存器(){
常量[loading,setLoading]=useState(false)
返回(
注册
{
console.log(正在加载)
//此处加载==预期为false
设置加载(真)
console.log(正在加载)
//此处加载==false,即使我将其设置为true
initFirebase()
firebase.auth().createUserWithEmailAndPassword(values.email,values.password)
。然后((res)=>{
console.log('done!')
})
.catch(函数(错误){
//在这里处理错误。
console.log(错误)
})
.最后(()=>{
console.log(正在加载)
//这里loading==false,尽管我希望它是真的
设置提交(错误)
设置加载(错误)
})
}
}
>
我同意这个建议
注册
)
}
尽管我的按钮
在某种程度上按预期工作(微调器按预期显示),但在控制台之后。通过提交
函数调用登录
加载的值,我注意到它是假
如果我预期它是真的。这是由于批处理useState
调用的方式造成的吗?
我的问题是:
控制台日志中加载==false
,为什么我的按钮按预期工作
Formik
提供了一个isSubmitting
标志,尝试使用它而不是跟踪您自己的加载状态,我知道它适用于您当前的规范,但当这个组件变得更复杂时,您可能会遇到一些问题
您的代码如下所示
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>
</>
);
}
导出默认函数寄存器(){
返回(
注册
{
试一试{
initFirebase();
等待火力基地
.auth()
.createUserWithEmailAndPassword(
values.email,
值。密码
);
}捕获(e){
//在这里处理错误。
console.log(错误);
}
}}
>
{({isSubmitting})=>(
我同意{“}
注册
)}
);
}
从这里开始我将首先检查onSubmit函数中setLoading()的计算结果。您可以定义一个伪函数,并查看它是否在onSubmit中正确触发。谢谢。我试图了解在这种情况下如何使用isSubmitting
标志?我仍然需要useState
,它仍然会批处理调用。我想我遗漏了什么?@Noob Nop,你没有遗漏任何东西,这就是异步函数的工作原理,你不能期望在异步调用后一行的值是不同的。我将用代码上的更改更新答案