ReactJS Formik动态食谱步骤输入值提交未捕获,求解决方案
问题:Formik提交时无法捕获烹饪步骤输入值
我正在构建一个食谱数据库,实现了点击“添加步骤”新增输入框、“删除最后一步”移除输入框的功能——输入框能正常显示和输入内容,但通过Formik提交表单时,步骤输入的信息完全没被捕获到。
现有代码片段
步骤输入区域代码:
<h4>Instructions</h4> {Array.from(Array(step)).map((c, index) => { const stepNumber = index + 1; return ( <Field type="text" name={`instructions[${index}]`} placeholder={`Instructions step ${stepNumber}`} component={Input} onChange={e => setIngredients(e.target.value)} /> ); })} <ButtonWrapper> <Button recipe type="button" onClick={() => handleInstructionRemove()} contain > Remove Last Instruction </Button> <Button color="green" contain type="button" onClick={() => setStep(step + 1)} > Add Step </Button> </ButtonWrapper>
状态管理与Formik配置:
const [step, setStep] = useState(1);
<Formik initialValues={{ title: "", author: "", ingredients: [], amount: [], size: [], temperature: "", degrees: "f", instructions: [], cookingTime: "", description: "", serving: "", category: "main", image: null }} validationSchema={RecipeSchema} onSubmit={async (values) => { try { const url = await handleUpload(); createRecipe(values, url); console.log(values); } catch (err) { console.log(err); } }} >
问题原因
- 自定义onChange覆盖Formik逻辑:给Field组件加了自定义的
onChange,错误调用setIngredients的同时,完全跳过了Formik默认的字段值同步流程,导致输入值根本没进到Formik的values里。 - 步骤数量与Formik数组不同步:删除步骤时只更新了本地
step状态,没同步缩短Formik的instructions数组,可能导致长度不匹配。
修复方案
1. 移除Field的自定义onChange
Formik的Field组件会自动根据name属性(这里的instructions[${index}])把输入值同步到对应的数组位置,不需要手动写onChange:
<h4>Instructions</h4> {Array.from(Array(step)).map((c, index) => { const stepNumber = index + 1; return ( <Field type="text" name={`instructions[${index}]`} placeholder={`Instructions step ${stepNumber}`} component={Input} // 删掉自定义onChange行 /> ); })}
2. 同步删除步骤时的Formik数组
修改handleInstructionRemove,同时更新本地step状态和Formik的instructions数组(需通过Formik的render props或useFormik钩子获取setValues方法):
// 假设在Formik的children组件内,通过props拿到setValues const handleInstructionRemove = () => { if (step <= 1) return; // 更新本地步骤数量 setStep(prev => prev - 1); // 同步缩短Formik的instructions数组 setValues(prevValues => ({ ...prevValues, instructions: prevValues.instructions.slice(0, -1) })); };
3. 初始化时保持状态与Formik数组一致
确保本地step初始值和Formik初始的instructions数组长度匹配:
// 从Formik的initialValues里取长度,无值则默认1 const [step, setStep] = useState(initialValues.instructions.length || 1);
额外说明
Formik已经帮你管理了表单所有字段的状态,包括数组类型的instructions,你只需要用step控制输入框的渲染数量即可,不需要额外用useState存储每个步骤的输入值。添加步骤时,Formik会自动在instructions数组中新增对应位置的内容,提交时就能完整捕获所有步骤的输入了。
内容的提问来源于stack exchange,提问作者Jacqueline
相关产品推荐
相关产品推荐

