React Material UI多TextField onChange状态更新失效求助
问题根因
输入框无响应是几个核心错误导致的:
onChange里的状态更新逻辑完全错误:执行setFormData({formData: value})会把整个formData状态替换为仅含formData属性的新对象,接口初始化的所有字段、其他输入框的已存值会被全量覆盖,且输入值没有绑定到当前字段对应的attri.datakey上,value={formData[attri.datakey]}永远读不到输入内容。- 属性排序逻辑有副作用:直接调用
sort()会修改原数组,且用map遍历赋值的写法只会拿到最后一个表单的属性,多表单场景下会丢字段。 - 用数组下标作为TextField的key,后续字段顺序调整时会出现状态错位。
可直接运行的修复代码
import { useState, useEffect, useMemo } from 'react'; // 组件内逻辑 const [formData, setFormData] = useState({}); useEffect(() => { fetch("/formdata") .then((res) => res.json()) .then((data) => setFormData(data)); }, []); // 缓存排序后的表单项,避免每次渲染重复排序、避免修改原数组 const attr = useMemo(() => { // 单表单场景直接取第一个,多表单场景可替换为flatMap合并所有formAttributes const targetForm = form.forms[0]; // 浅拷贝原数组后再排序,消除原数组修改副作用 return [...targetForm.formAttributes].sort((a, b) => a.order - b.order); }, [form.forms]); // 通用字段更新函数 const updateFormField = (dataKey, inputValue) => { setFormData(prevState => ({ ...prevState, // 保留所有已有字段值 [dataKey]: inputValue // 仅更新当前操作的字段 })) } return ( <> {attr.map((attri) => ( <TextField key={attri.datakey} // 用业务唯一标识作为key,避免状态错位 label={attri.label} value={formData[attri.datakey] || ""} onChange={e => updateFormField(attri.datakey, e.target.value)} /> ))} </> )
多表单合并字段的话,只需要把useMemo里的attr计算逻辑替换为
return form.forms.flatMap(form => [...form.formAttributes]).sort((a,b) => a.order - b.order)即可,核心状态更新逻辑不需要改动。
内容的提问来源于stack exchange,提问作者Seth
相关产品推荐
相关产品推荐

