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

如何实现React两个组件中公共组件的同步删除?

React组件任务同步删除问题解决方案

问题

有两个React组件TaskLists和Daycard,均使用公共组件TaskCard展示任务。在其中一个组件内调用API删除任务后,另一个组件中的对应TaskCard不会立即消失,需刷新浏览器才会移除。

原因

两个组件各自维护独立的tasks状态,删除操作仅更新了当前组件的本地状态,另一个组件的状态仍为旧数据,导致界面不同步。

解决方案

方案一:状态提升至共同父组件

将任务状态和删除逻辑提取到两个组件的共同父组件中,通过props传递给子组件,确保状态更新能同步到所有使用该状态的组件。

父组件示例(如App.js)

import React, { useEffect, useState } from "react";
import { getTasks, deleteTask } from "../api/task.api";
import { TaskLists } from "./TaskLists";
import { Daycard } from "./Daycard";

function App() {
  const [tasks, setTasks] = useState([]);

  // 初始化加载任务
  useEffect(() => {
    async function loadTasks() {
      const res = await getTasks();
      setTasks(res.data);
    }
    loadTasks();
  }, []);

  // 统一删除逻辑:先调用API,再更新状态
  const removeTask = async (id) => {
    await deleteTask(id);
    setTasks(tasks.filter(task => task.id !== id));
  };

  return (
    <div>
      <TaskLists tasks={tasks} onDelete={removeTask} />
      <Daycard hashv="your-hash-value" tasks={tasks} onDelete={removeTask} />
    </div>
  );
}

export default App;

改造TaskLists组件

import React from "react";
import { TaskCard } from "./TaskCard";

export function TaskLists({ tasks, onDelete }) {
  return (
    <div>
      {tasks.map((task) => (
        <TaskCard key={task.id} task={task} onDelete={onDelete} />
      ))}
    </div>
  );
}

改造Daycard组件

import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { TaskCard } from "./TaskCard";

export function Daycard({ hashv, tasks, onDelete }) {
  let b = 0;
  const [hash, setHash] = useState(hashv);
  const navigate = useNavigate();
  
  const handleClick = () => {
    if (b === 0) {
      navigate(`/tasks-create?hash=${hash}`);
      console.log(`the hash is ${hash}`);
    }
  };

  return (
    <div
      onClick={handleClick}
      className="col pb-5 bg-light border border-dark flex-grow-1"
      style={{ height: "auto" }}
    >
      {tasks.map((task) => {
        if (task.hash == hash) {
          b = 1;
          return <TaskCard key={task.id} task={task} onDelete={onDelete} />;
        }
      })}
    </div>
  );
}

方案二:使用React Context全局管理状态

若组件层级较深,状态提升不便,可通过Context全局共享任务状态和删除方法。

创建TaskContext.js

import React, { createContext, useContext, useEffect, useState } from "react";
import { getTasks, deleteTask } from "../api/task.api";

const TaskContext = createContext();

// 全局状态提供者
export function TaskProvider({ children }) {
  const [tasks, setTasks] = useState([]);

  useEffect(() => {
    async function loadTasks() {
      const res = await getTasks();
      setTasks(res.data);
    }
    loadTasks();
  }, []);

  const removeTask = async (id) => {
    await deleteTask(id);
    setTasks(tasks.filter(task => task.id !== id));
  };

  return (
    <TaskContext.Provider value={{ tasks, removeTask }}>
      {children}
    </TaskContext.Provider>
  );
}

// 自定义hooks,简化Context调用
export function useTasks() {
  return useContext(TaskContext);
}

根组件包裹Provider

import { TaskProvider } from "./TaskContext";
import { TaskLists } from "./TaskLists";
import { Daycard } from "./Daycard";

function App() {
  return (
    <TaskProvider>
      <TaskLists />
      <Daycard hashv="your-hash-value" />
    </TaskProvider>
  );
}

export default App;

改造TaskLists组件

import React from "react";
import { useTasks } from "./TaskContext";
import { TaskCard } from "./TaskCard";

export function TaskLists() {
  const { tasks, removeTask } = useTasks();

  return (
    <div>
      {tasks.map((task) => (
        <TaskCard key={task.id} task={task} onDelete={removeTask} />
      ))}
    </div>
  );
}

改造Daycard组件

import React, { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useTasks } from "./TaskContext";
import { TaskCard } from "./TaskCard";

export function Daycard({ hashv }) {
  let b = 0;
  const [hash, setHash] = useState(hashv);
  const navigate = useNavigate();
  const { tasks, removeTask } = useTasks();
  
  const handleClick = () => {
    if (b === 0) {
      navigate(`/tasks-create?hash=${hash}`);
      console.log(`the hash is ${hash}`);
    }
  };

  return (
    <div
      onClick={handleClick}
      className="col pb-5 bg-light border border-dark flex-grow-1"
      style={{ height: "auto" }}
    >
      {tasks.map((task) => {
        if (task.hash == hash) {
          b = 1;
          return <TaskCard key={task.id} task={task} onDelete={removeTask} />;
        }
      })}
    </div>
  );
}

方案三:删除后重新拉取数据(简单但效率较低)

在每个组件的删除方法中,调用删除API成功后,重新拉取最新任务列表更新本地状态。

改造TaskLists的removeTask

const removeTask = async (id) => {
  await deleteTask(id); // 确保API调用成功
  const res = await getTasks();
  setTasks(res.data);
};

改造Daycard的removeTask

const removeTask = async (id) => {
  await deleteTask(id);
  const res = await getTasks();
  setTasks(res.data);
};

注意:无论采用哪种方案,都要保证先成功调用删除API,再更新本地状态,避免出现本地状态与后端数据不一致的情况。


内容的提问来源于stack exchange,提问作者MrJonesBones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 02:05:55