React Formik中IFSC输入框失焦后无法填充银行信息求助
问题根源与解决方案
你的问题核心是同时维护了Formik内部状态和自定义state,导致状态不同步,加上ReusableTextField组件的实现有错误,导致自动填充无法生效。以下是具体修复步骤:
1. 修复ReusableTextField组件
你的自定义TextField组件存在两个关键问题:未定义的stateValue导致useEffect无效,以及手动传递value覆盖了Formik的状态管理。修改后的组件如下:
export const ReusableTextField = ({ label, name, type, error, helperText, onChange, ...rest }) => { const { touched, handleChange, values, setFieldValue } = useFormikContext(); const isError = Boolean(error); return ( <FormControl variant="outlined" fullWidth error={isError}> <Field as={TextField} name={name} label={label} fullWidth type={type} // 移除手动传递的value,让Formik自动管理状态 onChange={(event) => { handleChange(event); // 外部onChange可选,无需更新自定义state if (onChange) { onChange(name, event.target.value); } }} {...rest} /> {isError && touched[name] && <FormHelperText>{helperText}</FormHelperText>} </FormControl> ); };
2. 重构BankDetails组件,移除冗余状态并统一使用Formik管理
你不需要维护studentBankName、studBankDetails等自定义state,Formik已经帮你管理了表单状态。修改后的关键部分如下:
移除冗余state
删除这些不需要的状态变量:
// 删掉以下所有自定义state const [studBankDetails, setStudBankDetails] = useState(''); const [studentAccNo, setStudentAccNo] = useState(null); const [studentBankIfse, setStudentBankIfse] = useState(null); const [studentBankName, setStudentBankName] = useState(null); const [studentBankBranch, setStudentBankBranch] = useState(null); const [studentBankAddress, setStudentBankAddress] = useState(null);
修改handleOnBlur,用Formik的setFieldValue更新字段
在Formik的render回调中解构出setFieldValue,直接用它更新表单字段:
// 在Formik的render函数里新增解构setFieldValue {({ errors, touched, handleChange, handleSubmit, isSubmitting, setFieldValue }) => ( <> {/* ...其他代码 */} {/* 把handleOnBlur移到这里,直接使用setFieldValue */} const handleOnBlur = (e) => { const { name, value } = e.target; if (name === 'studIfsc') { const reg = { ifsc_code: value }; axios .post(serverIpAddress + '/api/v1/bank/validateIFSC', reg, { headers: { Authorization: `Bearer ${token}` } }) .then((response) => { const { BANK, BRANCH, ADDRESS } = response.data.pd; // 直接更新Formik的表单字段 setFieldValue('studBankName', BANK); setFieldValue('studBankBranch', BRANCH); setFieldValue('studBankAddress', ADDRESS); }) .catch((err) => { console.log('Error fetching ifsc info:', err); }); } }; {/* ...表单输入框代码 */} </> )}
调整ReusableTextField的props,移除手动传递的value
所有输入框不再需要手动传value,Formik会自动从上下文获取状态:
// 账号输入框 <ReusableTextField required variant="outlined" type="number" label="Account Number" name="studAccNo" onChange={handleChange} error={errors.studAccNo} /> // IFSC输入框 <ReusableTextField required variant="outlined" type="text" label="IFSC code" name="studIfsc" onChange={handleChange} error={errors.studIfsc} onBlur={handleOnBlur} /> // 银行名称输入框 <ReusableTextField required variant="outlined" type="text" label="Name of the bank" name="studBankName" onChange={handleChange} /> // 支行和地址输入框同理,移除value属性,使用Formik的handleChange
修复handleBackClick的错误
原代码中setValue和event未定义,修改如下:
// 先确保步骤状态已定义 const [stepValue, setStepValue] = useState(/* 你的初始步骤值 */); const handleBackClick = (event) => { event.preventDefault(); const instructions = {}; const newStep = stepValue - 1; setStepValue(newStep); onBack(instructions, newStep); };
3. 验证表单提交
现在所有表单状态都由Formik统一管理,提交时直接使用Formik传递的values即可:
onSubmit={async (formValues, { setErrors, setStatus, setSubmitting }) => { try { setIsLoading(true); // 直接使用formValues,无需依赖自定义state await postData(formValues); // ...后续逻辑 } catch (err) { setStatus({ success: false }); setErrors({ submit: err.message }); } }}
内容的提问来源于stack exchange,提问作者Sneha Narvekar
相关产品推荐
相关产品推荐

