You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 22:03:41