Formik内嵌Table时,设置输入框初始值后无法修改的问题求助
解决Formik表格内输入框无法修改的思路
核心问题根源
你直接将typeClient.label硬赋值给<Field>的value,等于绕过了Formik的状态管理机制——每次输入时,Formik会优先读取你硬设的初始值,导致输入内容被强制回滚。必须把列表数据完全纳入Formik的initialValues,通过name属性绑定状态,才能让输入框正常响应修改。
具体解决步骤
把列表数据映射到initialValues
将你的typeClients数组转换为Formik可管理的结构,比如新增一个数组字段clientTypes,每个元素对应原列表的属性:const initialValues = { clientTypes: typeClients.map(item => ({ label: item.label, id: item.id // 保留原数据标识,方便后续提交对应 })) };通过索引绑定Field的name属性
遍历Formik维护的values.clientTypes,给每个<Field>设置带索引的name路径,让Formik能精准追踪每行的状态:<Field name={`clientTypes[${index}].label`} type="text" />注意:不要手动设置
value属性,Formik会自动通过name关联initialValues和当前状态。维护行级编辑状态
用React的useState管理每行的编辑开关,比如:const [isEditing, setIsEditing] = useState(Array(typeClients.length).fill(false)); const toggleEdit = (index) => { const newState = [...isEditing]; newState[index] = !newState[index]; setIsEditing(newState); };点击"Update"时切换对应行的
isEditing状态,决定显示<Field>还是普通文本。
完整示例代码片段
import { Formik, Form, Field } from 'formik'; import { useState } from 'react'; // 假设你的原始列表数据 const typeClients = [ { id: 1, label: 'Client Type 1' }, { id: 2, label: 'Client Type 2' } ]; const ClientTable = () => { const [isEditing, setIsEditing] = useState(Array(typeClients.length).fill(false)); const toggleEdit = (index) => { const newState = [...isEditing]; newState[index] = !newState[index]; setIsEditing(newState); }; return ( <Formik initialValues={{ clientTypes: typeClients.map(item => ({ label: item.label, id: item.id })) }} onSubmit={(values) => { // 提交时直接获取修改后的数组 console.log('Updated data:', values.clientTypes); }} > {({ values }) => ( <Form> <table border="1"> <thead> <tr> <th>Client Type</th> <th>Action</th> </tr> </thead> <tbody> {values.clientTypes.map((type, index) => ( <tr key={type.id}> <td> {isEditing[index] ? ( <Field name={`clientTypes[${index}].label`} type="text" /> ) : ( type.label )} </td> <td> <button type="button" onClick={() => toggleEdit(index)}> {isEditing[index] ? 'Save' : 'Update'} </button> </td> </tr> ))} </tbody> </table> <button type="submit" style={{ marginTop: '10px' }}> Submit All Changes </button> </Form> )} </Formik> ); }; export default ClientTable;
关键注意事项
- 始终基于Formik的
values渲染表格内容,而非原始的typeClients数组,确保显示的是最新修改状态。 - 保留原数据的唯一标识(如
id),避免用数组索引作为key(数据顺序变化时会导致渲染异常)。 - 若需要单独保存单行数据,可在点击"Save"时调用Formik的
setFieldValue方法更新对应字段,再切换编辑状态。
内容的提问来源于stack exchange,提问作者Jean François Manatane
相关产品推荐
相关产品推荐

