You need to enable JavaScript to run this app. Formik表单无法将state中输入值传递给POST API的问题排查
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 13:45:04