
在 React 函数组件中,直接用 let itemList = [] 声明数组会导致每次组件重渲染时被重新初始化为空数组;正确做法是使用 useState 管理该数组,并在更新时基于前一个状态进行不可变操作。
在 react 函数组件中,直接用 `let itemlist = []` 声明数组会导致每次组件重渲染时被重新初始化为空数组;正确做法是使用 `usestate` 管理该数组,并在更新时基于前一个状态进行不可变操作。
React 函数组件的执行逻辑决定了:每次状态更新(如 updateItm 触发)都会导致整个 App 函数重新执行。因此,像 const itemList = [] 这样的局部变量声明,会在每次渲染时被重新赋值为空数组——这正是你观察到 itemList 始终只保留最新一项的原因。
要实现“累积添加”,必须将 itemList 也纳入 React 的状态管理体系,使用 useState 初始化,并通过函数式更新确保基于最新状态追加元素:
import { useState } from 'react';
function App() {
const [item, updateItem] = useState(''); // 初始值建议设为字符串,避免 undefined
const [itemList, setItemList] = useState([]); // ✅ 正确:用 useState 管理列表
const listenInput = (e) => {
updateItem(e.target.value);
};
const addItem = () => {
if (item.trim() === '') return; // 防止空项
setItemList(prev => [...prev, item]); // ✅ 不可变更新:展开旧数组 + 新项
updateItem(''); // 可选:清空输入框
};
return (
<div classname="main-div">
<div classname="center-div">
<h1>To Do</h1>
<input value="{item}" onchange="{listenInput}" type="text" name="item" placeholder="Add item"><button onclick="{addItem}">+</button>
<ol>
{itemList.map((it, idx) => (
<li key="{idx}">{it}</li>
))}
</ol>
</div>
</div>
>
);
}
export default App;
⚠️ 关键注意事项:
- 不要省略 value 属性:原代码中 缺少受控属性 value={item},会导致输入行为异常(如无法实时响应或失去焦点),务必补全;
- 避免直接修改状态数组:切勿使用 itemList.push() 或 itemList[itemList.length] = item,这会破坏 React 的响应式机制且无法触发重渲染;
- 使用函数式更新:setItemList(prev => [...prev, item]) 能确保获取到最新的状态快照,尤其在快速连续调用时更可靠;
- 添加防重复/空值校验:如示例中的 if (item.trim() === '') return,提升用户体验与数据质量。
总结:React 中所有需要跨渲染周期保持的数据,都应交由 useState、useRef 等 Hook 管理。局部变量仅适用于单次渲染内的临时计算,不可承载状态逻辑。











