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

React状态管理及Formik表单初始化值异常问题求助

问题解决方案

核心问题分析

  1. State初始化错误:你把info初始化为数组[],但接口返回的是单个对象,导致初始时info.name为undefined,且后续赋值对象会造成类型不匹配。
  2. Formik初始值未同步更新:useFormik的initialValues仅在组件首次挂载时初始化,后续info更新后不会自动同步到Formik的values中。
  3. 错误使用defaultValue:defaultValue是一次性的初始值,当组件后续重新渲染时不会更新,应该用Formik的values绑定到TextField的value属性。
  4. useEffect无限触发:未添加依赖数组,导致组件每次渲染都发起请求,浪费资源。

修改后的代码

import { useLocation, useEffect, useState } from 'react';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { Container, TextField, Button } from '@mui/material';
import axios from 'axios';

const YourComponent = () => {
  const location = useLocation();
  // 初始化为空对象,匹配接口返回的单个数据结构
  const [info, setInfo] = useState({});

  useEffect(() => {
    // 仅当location.state.id变化时发起请求,避免无限调用
    const fetchInfo = async () => {
      try {
        const response = await axios.get(`//localhost:3001/Info/${location.state.id}`);
        setInfo(response.data);
        // 请求完成后更新Formik的values
        formik.setValues({ name: response.data.name });
      } catch (error) {
        console.error('获取数据失败:', error);
      }
    };

    if (location.state?.id) { // 安全校验,避免id不存在时发起请求
      fetchInfo();
    }
  }, [location.state.id, formik.setValues]); // 添加依赖数组

  const validationSchema = Yup.object().shape({
    name: Yup.string().required('姓名不能为空') // 可根据需求添加校验规则
  });

  const formik = useFormik({
    initialValues: {
      name: '' // 初始设为空字符串,避免undefined
    },
    validationSchema: validationSchema,
    onSubmit: (values) => {
      console.log(values); // 现在能正确获取到表单值
    }
  });

  return (
    <>
      <Container>
        <form onSubmit={formik.handleSubmit}>
          <TextField
            id="name"
            label="Name"
            name="name"
            onChange={formik.handleChange}
            onBlur={formik.handleBlur}
            value={formik.values.name} // 绑定Formik的values,替代defaultValue
            error={formik.touched.name && Boolean(formik.errors.name)}
            helperText={formik.touched.name && formik.errors.name}
          />
          <Button type="Submit" variant="contained" sx={{ mt: 2 }}>
            Submit
          </Button>
        </form>
      </Container>
    </>
  );
};

export default YourComponent;

关键修改点说明

  • State初始化:将info初始化为{},与接口返回的对象结构一致。
  • useEffect优化:添加[location.state.id, formik.setValues]作为依赖,仅在id变化时请求,同时增加id存在性校验,避免报错。
  • Formik值同步:请求成功后调用formik.setValues更新表单值,确保Formik内部状态与接口数据同步。
  • TextField绑定:使用value={formik.values.name}替代defaultValue,让表单值完全由Formik控制,无需依赖key强制重渲染。
  • 添加校验规则:可选添加Yup校验,增强表单功能。

内容的提问来源于stack exchange,提问作者IT Cleanocean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 07:32:08