React.js中如何将对象传递给Formik表单填充初始值
问题根因
你出现这个问题是三处核心用法错误导致的:
- React组件不能作为普通函数手动调用,必须通过JSX语法渲染,同时要将需要传递的数据作为props传入
- React函数组件的第一个入参是整个props对象,你直接写
(student)拿到的不是你传的学生对象,而是包含了所有传入属性的props集合,所以打印会出现多余内容 - 你组件内使用了
props.onSuccess但没有接收props参数,同时Formik的initialValues里其他字段没有默认取学生对象的对应属性,也会导致初始值填充失败
修正方案
第一步:调整弹框打开逻辑和组件渲染方式
首先不要直接调用EditStudentForm函数,改为把选中的学生存在state里,在弹框的渲染位置传入组件:
// 打开编辑弹框的函数调整 openEditStudentModal = (student) =>{ this.setState({ isEditStudentFromVisible: true, currentEditStudent: student // 存储当前要编辑的学生对象 }); } // 表格行的Edit按钮渲染逻辑不变 render: (student ) => ( <Button onClick={() => this.openEditStudentModal(student)}> Edit </Button> ), // 弹框渲染位置调整,你可以把这段放在你原来渲染弹框的地方 { this.state.isEditStudentFromVisible && ( // 这里换成你实际用的弹框组件,比如antd的Modal <Modal visible={this.state.isEditStudentFromVisible} onCancel={() => this.setState({isEditStudentFromVisible: false})} > {/* 用JSX语法渲染表单组件,传入需要的props */} <EditStudentForm student={this.state.currentEditStudent} onSuccess={() => { // 编辑成功后的逻辑,比如关闭弹框、刷新学生列表 this.setState({isEditStudentFromVisible: false}) }} /> </Modal> ) }
第二步:调整EditStudentForm组件的参数接收和初始值配置
const inputMargin = { marginBottom: "10px" }; const tagStyle = { backgroundColor: "#f50", color: "white", ...inputMargin }; // 从props中解构出传入的student和onSuccess const EditStudentForm = ({student, onSuccess}) => { console.log(student) return ( <Formik enableReinitialize={true} initialValues={{ studentId: student.studentId || "", firstName: student.firstName || "", lastName: student.lastName || "", // 其他字段也默认取学生对象的对应值,不存在就设为空 email: student.email || "", gender: student.gender || "", }} validate={(values) => { const errors = {}; 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改成values,避免和外层的student变量重名混淆 onSubmit={(values, { setSubmitting }) => { editStudent(values).then(() => { // 直接使用解构出来的onSuccess,不需要再取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 EditStudentForm;
内容的提问来源于stack exchange,提问作者Marquez Ludin Albarado Jaimes
相关产品推荐
相关产品推荐

