点击登录时React Hook返回initState初始值 无法校验Formik输入数据如何解决
问题核心原因
你遇到的不是Hook首次渲染强制返回初始值的问题,本质是React状态更新的异步批量处理机制导致的:
在同一个事件回调执行上下文里,调用setState更新状态后,当前上下文中的状态变量还是更新前的旧值,要等整个事件回调执行完毕后,React才会批量完成状态更新、触发组件重渲染,重渲染后的新状态才能被读取到。这也是你看到修改后的状态总是在点击后下一次打印才生效的原因。
解决方案
方案1(推荐,适配你当前用Formik的场景)
你已经引入了Formik就不需要额外用useState单独存储账号密码,Formik本身已经托管了所有表单的实时输入值,你直接在登录提交逻辑中读取Formik的values对象即可拿到最新的输入内容,完全不会有状态不同步的问题,示例用法:
import { useFormik } from 'formik'; function LoginPage() { const formik = useFormik({ initialValues: { username: '', password: '' }, // 登录提交逻辑直接写在onSubmit里 onSubmit: (values) => { // 直接拿values里的最新值做校验即可 const validateResult = values.username === '1234' && values.password === '你的校验密码'; console.log(validateResult); // 后续登录逻辑... } }); return ( <form onSubmit={formik.handleSubmit}> <input name="username" onChange={formik.handleChange} value={formik.values.username} placeholder="用户名" /> <input name="password" type="password" onChange={formik.handleChange} value={formik.values.password} placeholder="密码" /> <button type="submit">登录</button> </form> ) }
方案2(如果需要保留自定义useState存储)
如果你要继续用自己的useState存账号密码,不要在调用setState后立刻读取状态做校验,两种修正方式:
- 直接从输入事件/Formik托管值里拿到最新的输入内容做校验,不用读取自己存的state
- 把校验逻辑放到
useEffect中,监听账号密码的状态变化,状态更新后自动执行校验:
const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); useEffect(() => { // 这里拿到的永远是更新后的最新状态 const validateResult = username === '1234' && password === '校验密码'; console.log(validateResult); }, [username, password])
内容的提问来源于stack exchange,提问作者Lê Quốc Khánh
相关产品推荐
相关产品推荐

