如何在React的useState钩子中更新数组对象属性并新增条目?
问题修复方案
你代码的核心问题是todo状态为数组类型,但更新时错误传入了对象结构,导致原数组被覆盖,无法正常渲染列表。正确的更新逻辑为展开原有数组后,追加新的todo对象即可,具体修改如下:
修复后完整代码
import { useState } from "react"; export default function Add() { // 原todo是数组,更新时要保持数组类型 const [todo, addTodo] = useState([{ name: "cat", time: "2 minutes ago" }]); const [list, setList] = useState(""); // 初始化空字符串避免受控组件警告 const add = () => { // 增加空输入判断,避免新增空条目 if (!list.trim()) return; // 展开原有数组,追加新的todo对象,不会删除原有内容 addTodo([ ...todo, { name: list, time: new Date().toLocaleString() // 可以自定义时间格式,和原有结构对齐 } ]); // 新增后清空输入框 setList(""); }; return ( <div> <input type="text" value={list} onChange={(e) => setList(e.target.value)} /> <button onClick={add}>Add new</button> {todo.map((item, i) => ( <li key={i}> {item.name} <span style={{ marginLeft: "15px" }}>{item.time}</span> </li> ))} </div> ); }
主要修改说明
- 修正状态更新逻辑:
addTodo传入数组而非对象,通过...todo展开原有所有条目,再追加新对象,保证原有内容不丢失 - 初始化
list为空字符串,避免React受控组件的无值警告 - 新增空输入校验,过滤无效提交
- 新增提交后清空输入框的逻辑,优化使用体验
- 补全新增对象的
time属性,和原有数组内的对象结构保持一致
内容的提问来源于stack exchange,提问作者Ghulam Azam Khan
相关产品推荐
相关产品推荐

