React中父组件状态变更后子组件无法更新的问题排查
React Todo应用添加任务后列表不更新问题排查
问题描述
我正在学习React官方文档,尝试实现一个Todo应用,代码和文档基本一致,仅列表无编辑/删除功能。
输入内容点击添加按钮后,TaskList组件未更新,但React DevTools显示任务已添加至列表。按概念,任务保存在父组件TaskApp的state中,状态变更应更新props并触发TaskList重渲染,但实际未发生。想了解遗漏的概念点,官方文档未用额外hooks却能正常运行。
代码片段
TaskApp.js
import React, { useState } from "react"; import AddTask from "./AddTask"; import TaskList from "./TaskList"; const initialsTasks = [ { id: 10, text: "Visit Paris", done: false }, { id: 11, text: "Visit Tokyo", done: true }, { id: 12, text: "Visit Washington DC", done: false } ]; let nextId = 13; function TaskApp() { const [tasks, setTasks] = useState(initialsTasks); function handleAddTask(text) { setTasks((prevTasks) => { return [ ...prevTasks, { id: nextId++, task: text, done: false } ]; }); } return ( <div className="task-app"> <h3>World Itinerary</h3> <AddTask onAddTask={handleAddTask} /> <TaskList tasks={tasks} /> </div> ); } export default TaskApp;
AddTask.js
import { useState } from "react"; export default function AddTask({ onAddTask }) { const [text, setText] = useState(""); function handleChange(e) { setText(e.target.value); } function handleClick() { onAddTask(text); setText(""); } return ( <div className="add-task"> <input type="text" placeholder="Add Task" value={text} onChange={handleChange} /> <button onClick={handleClick}>Add</button> </div> ); }
TaskList.js
export default function TaskList({ tasks }) { return ( <div className="task-list"> {tasks.map((task) => { return ( <div className="task" key={task.id}> {task.text} </div> ); })} </div> ); }
问题原因与解决方法
问题核心是新任务的字段名不匹配:
- 你在
handleAddTask中创建新任务时,字段名写的是task: text,但初始任务列表和TaskList渲染时用的都是text字段。 - 这就导致新添加的任务对象没有
text属性,TaskList渲染时自然看不到内容,看起来像是组件没更新。
修正很简单,把handleAddTask里的task: text改成text: text即可:
function handleAddTask(text) { setTasks((prevTasks) => { return [ ...prevTasks, { id: nextId++, text: text, // 修正字段名 done: false } ]; }); }
关于你困惑的重渲染问题:其实React的状态更新机制是正常工作的,组件已经触发了重渲染,只是因为字段错误导致渲染内容为空,才让你误以为没更新。你对React状态驱动渲染的概念理解是正确的,只是犯了一个字段名匹配的小失误。
内容的提问来源于stack exchange,提问作者Nesh
相关产品推荐
相关产品推荐

