React状态管理及Formik表单初始化值异常问题求助
问题解决方案
核心问题分析
- State初始化错误:你把
info初始化为数组[],但接口返回的是单个对象,导致初始时info.name为undefined,且后续赋值对象会造成类型不匹配。 - Formik初始值未同步更新:
useFormik的initialValues仅在组件首次挂载时初始化,后续info更新后不会自动同步到Formik的values中。 - 错误使用defaultValue:
defaultValue是一次性的初始值,当组件后续重新渲染时不会更新,应该用Formik的values绑定到TextField的value属性。 - 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
相关产品推荐
相关产品推荐

