React受控输入+Formik实现用户资料编辑时状态异常排查
解决Formik受控输入用户姓名显示异常的问题
问题根源
你当前的实现存在三个核心问题:
- 初始值异步问题:组件挂载时
props.props.firstName可能还未加载完成,导致useState初始值为undefined - useEffect依赖错误:监听的是
firstName状态而非props.props.firstName,不仅无法同步props更新,还会触发不必要的状态更新循环 - 双状态冲突:同时维护Formik的表单状态和自己的
firstName状态,导致数据同步混乱,出现显示异常
修复方案
直接利用Formik的表单状态管理输入,移除额外的firstName状态,通过Formik的initialValues和setValues方法同步props数据:
const PersonalInformation = (props: any) => { const [open, setOpen] = useState(false); const formikRef = useRef<any>(null); // 监听props变化,同步更新Formik表单值 useEffect(() => { if (formikRef.current && props.props.firstName) { formikRef.current.setValues({ firstName: props.props.firstName }); } }, [props.props.firstName]); console.log('prop firstName:', props.props.firstName); return ( <Box> <NotificationBar open={open} setOpen={setOpen} message="notifMessage" type="info" /> <Typography variant="subtitle2" component="div"> Personal Information </Typography> <Formik initialValues={{ firstName: props.props.firstName ?? '', lastName: '', phone: '', }} onSubmit={() => { // 提交逻辑 }} validationSchema={changePersonalInfos} innerRef={formikRef} > {(formik) => ( <Form onSubmit={formik.handleSubmit}> <Grid container spacing={2}> <Grid item xs={6}> <InputField label="First Name" value={formik.values.firstName} onChange={formik.handleChange} name="firstName" /> <CustomError name="firstName" component="div" /> </Grid> {/* 其他表单字段 */} </Grid> </Form> )} </Formik> </Box> ); };
关键修改说明
- 移除冗余状态:删除自己维护的
firstName状态,完全依赖Formik管理表单数据,避免双状态冲突 - 安全初始化:
initialValues中用props.props.firstName ?? ''处理可能的undefined,确保初始显示正常 - 同步props更新:通过
useEffect监听props.props.firstName变化,使用Formik的setValues方法同步表单值,确保外部props更新时表单内容跟着变化 - 简化输入绑定:输入框直接使用
formik.values.firstName作为值,formik.handleChange处理变更,同时设置name属性让Formik正确识别字段
内容的提问来源于stack exchange,提问作者Aymen khlil
相关产品推荐
相关产品推荐

