React useState使用扩展运算符存储多条state数据的正确方法
React useState 数组追加数据覆盖旧内容修复方案
问题原因
你当前的代码存在两个核心错误,导致每次更新都会覆盖原有数组内容:
setArr([{ file, ...Arr, newData }])每次执行都会生成一个长度固定为1的新数组,数组内仅包含一个对象,完全没有保留旧数组的元素结构- 错误将数组扩展运算符写在了对象字面量内部:
...Arr在对象中会把数组的索引作为键展开为对象属性,根本不是数组追加元素的正确写法,最终生成的对象结构完全不符合预期。
正确实现代码
const [title, setTitle] = useState(""); const [desc, setDesc] = useState(""); const [file, setFile] = useState<any[]>([]); const [Arr, setArr] = useState<any[]>([]); const AddHandle = () => { // 组装要追加的新条目 const newItem = { title: title, desc: desc, file: file }; // 用函数式更新拿到最新的旧状态,展开旧数组后追加新条目,不会覆盖原有内容 setArr(prevArr => [...prevArr, newItem]); // 重置输入状态 setDesc(""); setTitle(""); setFile([]); // 如果需要提交后清空已选文件可以放开这行,根据业务需求调整 };
注意事项
- 数组类型state追加元素的标准写法是
[...旧数组, 新元素],会生成包含所有旧元素和新元素的全新数组,符合React不可变更新的要求 - 优先使用函数式更新写法
setXxx(prevState => 新值),可以避免React state异步更新导致的闭包拿到旧值、数据丢失问题 - 不建议长期用
any做类型标注,可以根据业务定义具体的接口类型,获得更好的类型提示:interface ArrItem { title: string; desc: string; file: File[]; } const [Arr, setArr] = useState<ArrItem[]>([]);
内容的提问来源于stack exchange,提问作者unknown coder
相关产品推荐
相关产品推荐

