You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

提交时Formik获取API值为Undefined问题求助

Formik提交API加载的表单时值为Undefined的解决方法

问题根源分析

你的代码存在几个关键问题导致提交时表单值为undefined:

  • 初始值设置错误:datas是数组类型,直接访问datas.name会返回undefined,数组本身没有name属性,需要从数组元素中取值。
  • 输入框未与Formik状态绑定:TextField直接硬写API返回的datas.name作为value,没有关联Formik的内部状态,导致Formik无法追踪输入框的变化。
  • 函数拼写错误:handleCange应为handleChange,虽然不影响功能,但属于代码规范问题。
  • Form结构不合理:将Form组件嵌套在数组循环中,每个用户生成独立的Form,与外层Formik上下文冲突。

修正后的代码

import React, { useState, useEffect } from "react";
import "./styles.css";
import { Box, Button, TextField } from "@mui/material";
import { Formik, Form, useFormikContext } from "formik";

export default function App() {
  const [datas, setDatas] = useState([]);
  const [searchId, setSearchId] = useState("");

  useEffect(() => {
    if (!searchId) return;
    fetch(`https://jsonplaceholder.typicode.com/users/?id=${searchId}`)
      .then((response) => response.json())
      .then((data) => setDatas(data));
  }, [searchId]);

  const handleChange = (e) => {
    setSearchId(e.target.value);
  };

  const UserTextField = ({ user }) => {
    const { values, handleChange, handleBlur } = useFormikContext();
    return (
      <TextField
        className="field"
        label="name"
        name="name"
        type="text"
        id="name"
        variant="filled"
        value={values.name || user.name}
        onBlur={handleBlur}
        onChange={handleChange}
        sx={{ gridColumn: "span 2" }}
      />
    );
  };

  return (
    <Formik
      initialValues={{ name: datas[0]?.name || "" }}
      enableReinitialize={true}
      onSubmit={(data, { resetForm }) => {
        console.log(data);
        resetForm();
      }}
    >
      {() => (
        <div className="App">
          <h1>搜索用户(输入1-5之间的ID)</h1>
          <div className="searchBox">
            <input
              type="text"
              placeholder="输入用户ID"
              onChange={handleChange}
              value={searchId}
            />
          </div>
          <div className="itemsSec">
            <Form>
              {datas.map((user) => (
                <div key={user.id} className="items">
                  <Box>
                    <UserTextField user={user} />
                  </Box>
                  <Button type="submit" color="secondary" variant="contained">
                    提交
                  </Button>
                </div>
              ))}
            </Form>
          </div>
        </div>
      )}
    </Formik>
  );
}

关键修改说明

  1. 修正初始值逻辑:使用datas[0]?.name || "",通过可选链操作符避免数组为空时报错,空数组时初始值设为空字符串。
  2. 绑定Formik状态:通过useFormikContext获取Formik的上下文方法,让输入框的值与Formik内部状态同步,确保提交时能获取到正确值。
  3. 优化搜索输入框:给搜索输入框添加value={searchId},避免React受控组件警告,同时修正事件处理函数拼写。
  4. 调整Form结构:将Form组件移到循环外层,确保Formik能正确管理整个表单的状态。
  5. 过滤无效请求:在useEffect中判断searchId为空时不发起API请求,减少无效调用。

内容的提问来源于stack exchange,提问作者Dwain Botha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:20:26