如何为React Formik学生编辑表单预填充对应表格行的学生数据
实现步骤
第一步:父组件新增状态存储当前编辑的学生数据
在渲染表格的父组件state中新增editingStudent字段,用于存储点击编辑按钮时对应行的学生数据,同时修改模态框打开方法接收入参:
state = { // 保留原有其他状态,例如模态框显隐状态 modalVisible: false, editingStudent: null } openEditStudentModal = (student) => { this.setState({ editingStudent: student, modalVisible: true }) }
第二步:修改编辑按钮点击事件,传递当前行学生数据
调整表格列的render配置,把当前行的student对象传入点击事件:
{ title:"", key:"button", // 原有代码Key拼写错误改为小写k,buttom修正为button render:(value, student)=>(<Button onClick={() => this.openEditStudentModal(student)}>Edit</Button>) }
第三步:改造EditStudentForm组件,接收外部传入的初始值
修改Formik配置,新增enableReinitialize={true}属性保证切换编辑的学生时表单会刷新初始值,初始值优先取props传入的学生数据:
const EditStudentFrom = (props) => ( <Formik // 优先取props传入的编辑数据,无数据时用默认空值兜底 initialValues={props.editingStudent || {studentId:"", firstName: "", lastName: "", email: "", gender: "" }} // 必须加这个属性,保证初始值变化时表单会自动重置 enableReinitialize={true} // 原有validate校验逻辑保持不变即可 validate={(values) => { const errors = {}; // 原有校验逻辑不变,注意:原有gender校验规则里的"MALE "多了一个空格,会导致匹配失败,建议改成"MALE" if (!values.firstName) { errors.firstName = "First name required"; } if (!values.lastName) { errors.lastName = "Last name required"; } if (!values.email) { errors.email = " Email required"; } else if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email) ) { errors.email = "Invalid Email address"; } if (!values.gender) { errors.gender = "Gender required"; } else if ( !["MALE", "male", "female", "FEMALE"].includes(values.gender) ) { errors.gender = "Gender most be ( MALE , male , FEMALE, female )"; } return errors; }} // 原有提交逻辑无需修改,student对象已包含studentId可直接传给接口 onSubmit={(student, { setSubmitting }) => { editStudent(student.studentId,student).then(() => { props.onSuccess(); setSubmitting(false); }); }} > {/* 原有表单渲染逻辑保持不变 */} {({ values, errors, touched, handleChange, handleBlur, handleSubmit, isSubmitting, submitForm, isValid, }) => ( <form onSubmit={handleSubmit}> <Input style={inputMargin} name="firstName" onChange={handleChange} onBlur={handleBlur} value={values.firstName} placeholder="First name" /> {errors.firstName && touched.firstName && ( <Tag style={tagStyle}>{errors.firstName}</Tag> )} <Input style={inputMargin} name="lastName" onChange={handleChange} onBlur={handleBlur} value={values.lastName} placeholder="Last name" /> {errors.lastName && touched.lastName && ( <Tag style={tagStyle}>{errors.lastName}</Tag> )} <Input style={inputMargin} type="email" name="email" onChange={handleChange} onBlur={handleBlur} value={values.email} placeholder="Email" /> {errors.email && touched.email && ( <Tag style={tagStyle}>{errors.email}</Tag> )} <Input style={inputMargin} name="gender" onChange={handleChange} onBlur={handleBlur} value={values.gender} placeholder="Gender" /> {errors.gender && touched.gender && ( <Tag style={tagStyle}>{errors.gender}</Tag> )} <Button onClick={() => submitForm()} type="submit" disabled={isSubmitting || (touched && !isValid)} > Submit </Button> </form> )} </Formik> ); export default EditStudentFrom;
第四步:Modal中渲染表单时传递editingStudent属性
在父组件的Modal内容里,把state中存储的当前编辑学生数据传给表单组件:
<Modal visible={this.state.modalVisible} // 其他Modal的配置项保持不变 > <EditStudentFrom editingStudent={this.state.editingStudent} onSuccess={() => { // 编辑成功后的业务逻辑,例如关闭模态框、刷新表格列表 this.setState({modalVisible: false}) this.loadStudentList() }} /> </Modal>
补充说明
原有代码可以同步修复几个小问题避免异常:
- 表单组件名
EditStudentFrom拼写错误,建议修正为EditStudentForm- 提交按钮的disabled判断里用了位运算符
|,建议改成逻辑或||更符合语义也避免异常
内容的提问来源于stack exchange,提问作者Marquez Ludin Albarado Jaimes
相关产品推荐
相关产品推荐

