Formik表单无法将state中输入值传递给POST API的问题排查
问题分析与修复方案
存在的问题
1. 输入框无法实时回显
- 受控
TextInput同时设置了defaultValue和value属性:defaultValue仅用于非受控组件的初始值赋值,受控组件绑定value后再设置defaultValue会触发更新冲突,导致输入的新值无法同步渲染到视图。 - 手机号输入框下方的错误提示存在笔误,误用了
name字段的校验状态,实际应该取phoneNo字段的touched和errors值。 - Formik本身的
values已经是受控数据源,不需要依赖profileItems状态实现回显,你注释的profileItems状态更新逻辑仅用于同步本地数组和表单值,不影响输入回显。
2. 直接传profileItems后端无法接收
- 请求头设置的是
Content-Type: multipart/form-data,该格式要求body必须为FormData实例,直接传递数组不会被自动转换为后端可识别的键值对结构,因此解析失败。 - 若要直接传
profileItems,需要将请求头改为Content-Type: application/json,同时用JSON.stringify(profileItems)序列化body,但需要后端配合调整参数解析逻辑,复用现有FormData方案改造成本更低。
修复后的代码
Formik组件部分
<Formik enableReinitialize={true} initialValues={{ name: profileItems[0].value, // 接口返回的初始值 phoneNo: profileItems[1].value, email: profileItems[2].value, address: profileItems[3].value, }} validationSchema={profileSchema} // 冗余的validator逻辑可直接删除 onSubmit={(values) => { // 每次提交新建FormData,避免旧值重复追加 const formData = new FormData(); formData.append("name", values.name); formData.append("phoneNo", values.phoneNo); formData.append("email", values.email); formData.append("address", values.address); // 同步更新本地profileItems状态,保持和表单值一致 const currentItems = [...profileItems]; currentItems[0].value = values.name; currentItems[1].value = values.phoneNo; currentItems[2].value = values.email; currentItems[3].value = values.address; setProfileItems(currentItems); postCustomer(formData); }} > {(props) => ( <> <View> {/* 姓名输入框 */} <TextInput title={profileItems[0].title} name="name" onBlur={props.handleBlur("name")} onChangeText={props.handleChange("name")} value={props.values.name} /> <Text style={styles.errorText}> {props.touched.name && props.errors.name} </Text> {/* 手机号输入框 */} <TextInput title={profileItems[1].title} name="phoneNo" onBlur={props.handleBlur("phoneNo")} onChangeText={props.handleChange("phoneNo")} value={props.values.phoneNo} /> <Text style={styles.errorText}> {/* 修复原笔误,使用phoneNo的校验状态 */} {props.touched.phoneNo && props.errors.phoneNo} </Text> <AppButton title="Save" style={styles.button} titleStyle={styles.textBtn} onPress={props.handleSubmit} /> </> </> )} </Formik>
接口请求部分优化
如果提交FormData时出现解析异常,可以删除手动设置的multipart/form-data请求头,运行环境会自动生成带边界标识的Content-Type,避免手动配置错误:
const postCustomer = (formData) => { fetch(`${apiUrl.baseURL}post_customer.php`, { method: "POST", headers: { Accept: "application/json", // 移除手动设置的Content-Type,让环境自动生成 }, body: formData, }) .then((response) => response.json()) .catch((error) => { console.error(error); throw error; }); };
内容的提问来源于stack exchange,提问作者Copy Paste
相关产品推荐
相关产品推荐

