You need to enable JavaScript to run this app. React 中如何跨组件基于_id实现共享数组的增删改操作
优惠活动
大模型
产品
解决方案
定价
更多

React 中如何跨组件基于_id实现共享数组的增删改操作

跨组件状态修改的实现方案

核心原则

React 中兄弟组件需要共享、操作同一份数据时,必须把状态提升到两个兄弟组件的最近共同父组件中,所有的状态修改逻辑都写在父组件里,再通过props把数据和修改方法分别下发给子组件。

现有代码存在几个新手常见的问题,会导致逻辑跑不通,我们逐个修正:

  • 在FirstChild里把父组件传入的props同步存到自身state,属于反模式:父组件状态更新时,子组件不会重新同步state,渲染结果永远是旧数据
  • SecondChild没有拿到父组件的状态修改方法,根本没有触发状态变更的入口
  • FirstChild的map渲染存在变量大小写错误:map参数定义为大写的Object,渲染时却用小写的object,代码直接报引用错误
  • 输入框没有绑定受控状态,拿不到用户输入的操作参数
  • 按钮设置type=Submit但没有配套form表单,点击会触发浏览器默认页面刷新,清空所有状态

分步修正代码

1. 父组件Parent:承载共享状态、定义修改方法

把数组状态、删除方法、更新方法都写在父组件中,通过props分别下发给两个子组件:

import React from "react";
import initialArrayData from "./ArrayComponent";
import FirstChild from "./FirstChild";
import SecondChild from "./SecondChild";

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      arrayData: initialArrayData,
      collapsed: false
    };
    // 绑定方法的this指向,避免调用时丢失上下文
    this.handleDelete = this.handleDelete.bind(this);
    this.handleUpdate = this.handleUpdate.bind(this);
  }

  // 删除指定_id的数组条目
  handleDelete(targetId) {
    this.setState(prevState => ({
      arrayData: prevState.arrayData.filter(item => item._id !== Number(targetId))
    }));
  }

  // 按_id判断是更新已有条目,还是新增条目
  handleUpdate(targetId, newTitle) {
    this.setState(prevState => {
      const idNum = Number(targetId);
      const existIndex = prevState.arrayData.findIndex(item => item._id === idNum);
      let newArray;
      if (existIndex > -1) {
        // id存在:替换对应条目的title
        newArray = [...prevState.arrayData];
        newArray[existIndex] = { _id: idNum, title: newTitle };
      } else {
        // id不存在:把新条目追加到数组末尾
        newArray = [...prevState.arrayData, { _id: idNum, title: newTitle }];
      }
      return { arrayData: newArray };
    });
  }

  render() {
    const { arrayData } = this.state;
    return (
      <>
        {/* 把数组数据传给FirstChild做渲染 */}
        <FirstChild data={arrayData} />
        {/* 把状态修改方法传给SecondChild做操作触发 */}
        <SecondChild onDelete={this.handleDelete} onUpdate={this.handleUpdate} />
      </>
    );
  }
}

export default Parent;

2. 渲染组件FirstChild:去掉冗余state,直接读props渲染

删除子组件内部存数组的冗余逻辑,直接从父组件的props拿数据渲染,修正变量大小写问题:

import React from "react";

class FirstChild extends React.Component {
  render() {
    const { data } = this.props;
    const renderArray = data.slice(0, 5).map(item => {
      // 列表项必须带唯一key属性
      return <h1 key={item._id}>{item._id} - {item.title}</h1>
    })
    return (
      <>
        {renderArray}
      </>
    );
  }
}

export default FirstChild;

3. 操作组件SecondChild:绑定输入值,调用父组件方法

用组件内的临时state存用户在输入框里填的操作参数,触发按钮点击时调用父组件传下来的修改方法:

import React, { useState } from "react";

const SecondChild = ({ onDelete, onUpdate }) => {
  // 存删除操作的目标_id值
  const [deleteId, setDeleteId] = useState("");
  // 存更新/新增操作的参数
  const [updateId, setUpdateId] = useState("");
  const [updateTitle, setUpdateTitle] = useState("");

  return (
    <>
      <input 
        type="text" 
        placeholder="输入要删除的_id值" 
        value={deleteId}
        onChange={(e) => setDeleteId(e.target.value)}
      />
      <button 
        type="button" 
        onClick={() => onDelete(deleteId)}
      >
        删除
      </button>

      <br />

      <input 
        type="text" 
        placeholder="输入条目_id" 
        value={updateId}
        onChange={(e) => setUpdateId(e.target.value)}
      />
      <input 
        type="text" 
        placeholder="输入条目title" 
        value={updateTitle}
        onChange={(e) => setUpdateTitle(e.target.value)}
      />
      <button 
        type="button" 
        onClick={() => onUpdate(updateId, updateTitle)}
      >
        更新/新增
      </button>
    </>
  );
}

export default SecondChild;

关键注意事项

  • 永远不要把父组件传入的props直接同步到子组件的state里做渲染源,只要父组件状态更新,直接从props读值就能拿到最新数据,存到state里会导致数据不同步
  • 修改数组/对象类型的state时,绝对不要直接修改原引用,必须返回一个新的数组/对象,否则React检测不到状态变化,不会触发重渲染
  • 遍历数组渲染列表时,必须给每个渲染项加上唯一的key属性,避免渲染错乱
  • 没有配套form表单的按钮,不要设置type=Submit,否则点击会触发浏览器默认刷新行为,清空所有React状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 06:15:03