React中如何向Map类型state的数组值中push元素并更新状态?
问题根源
React state更新依赖浅比较检测变化,要求state是不可变数据:你直接修改原有Map实例的内容(调用set、修改数组执行push)都属于在原有引用上做变更,React检测不到引用变化,自然不会触发重渲染。
你之前的写法setTasksMap(tasksMap.set(key, []))之所以能运行但拿到空数组,是因为Map.prototype.set返回的是当前Map实例本身,你在调用setter的时候还没执行后续的push操作,后续对数组的修改都是在已经提交给state的Map实例上操作的,React无法感知到这次变更。
正确实现方式
所有修改都要先拷贝生成新的Map实例,所有变更都在新实例上完成后,再把新实例传递给setTasksMap触发更新。
批量构建Map的写法
如果要一次性处理多个task更新Map:
const [tasksMap, setTasksMap] = useState(new Map()); // 处理tasks逻辑 const updateTasksMap = (tasks, week) => { // 基于原有Map拷贝新实例 const newTasksMap = new Map(tasksMap); tasks.forEach((task) => { const key = `${week.year}-${week.weekNo}`; // 数组也要做不可变更新,不要直接push修改原数组 const taskList = newTasksMap.get(key) || []; newTasksMap.set(key, [...taskList, task]); }); // 提交新的Map实例触发更新 setTasksMap(newTasksMap); }
单个key增量更新的写法
如果只需要给指定key新增单个task,推荐用函数式更新避免闭包陷阱:
const addTask = (newTask, week) => { const key = `${week.year}-${week.weekNo}`; setTasksMap(prevMap => { const newMap = new Map(prevMap); const currentTasks = newMap.get(key) || []; newMap.set(key, [...currentTasks, newTask]); return newMap; }); }
内容的提问来源于stack exchange,提问作者John Doener
相关产品推荐
相关产品推荐

