
在 React 函数组件中,直接用 const itemList = [] 声明数组会导致每次组件重渲染时被重新初始化为空数组,无法累积数据;正确做法是使用 useState 或 useRef 管理该数组状态。
在 react 函数组件中,直接用 `const itemlist = []` 声明数组会导致每次组件重渲染时被重新初始化为空数组,无法累积数据;正确做法是使用 `usestate` 或 `useref` 管理该数组状态。
你遇到的问题非常典型:itemList 被定义为普通常量 const itemList = [],它不是 React 状态,而是一个在每次函数组件执行(即每次渲染)时都会重新创建的局部变量。当用户输入新值并触发 updateItm 后,React 会重新调用 App() 函数 —— 此时 itemList 被重置为空数组,push() 操作只是往这个全新的空数组里添加一个元素,因此永远只看到单个最新项。
✅ 正确解法:将 itemList 升级为受控状态
推荐使用 useState 管理列表,确保其跨越渲染周期保持一致:
import { useState } from 'react';
function App() {
const [item, updateItem] = useState('');
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;
? 关键改进说明:
- setItemList(prev => [...prev, item]) 使用函数式更新,确保获取到最新状态,避免闭包陷阱;
- 为 添加 value={item} 实现受控组件,避免状态与 DOM 不同步;
- 列表渲染使用 .map() 并赋予 key,符合 React 最佳实践;
- 添加 trim() 校验,提升健壮性。
⚠️ 补充说明:
若你仅需在内存中暂存、不触发重渲染(例如记录日志、缓存中间计算),可改用 useRef:
const itemListRef = useRef([]);
// ...
const addItem = () => {
itemListRef.current.push(item);
console.log(itemListRef.current); // ✅ 持久存在,但不会引起重渲染
};
但注意:useRef 不会触发视图更新,因此不能直接用于驱动 UI 渲染(如
适用于用户提出以下需求时:“构建赢回活动(win-back campaign)”、“重新激活已流失订阅者(re-engage lapsed subscribers)”、“执行重新授权 / 重新同意(re-permission / re-consent)清理”或“清理无效联系人列表(sunset my dead list)”;输出一个闭环式再激活方案——包括:流失用户群组(lapsed-cohort)定义、分阶段优惠阶梯(staged offer ladder)、重新授权(re-consent / re-p
- 列表)——此时必须搭配 useState。
总结:React 函数组件中的“变量”不具备实例生命周期,所有需要跨渲染保留的数据,都应通过 useState、useRef 或其他 Hook 显式声明和管理。










