React复用组件共用同一份数据时删除操作互相影响的问题咨询
问题根源
所有复用的<ShotList>组件共用了App组件中同一份全局data状态,删除操作直接修改了公共数据源,因此所有绑定该数据的组件都会同步触发更新,导致其他组件的数据也被删除。
优化实现方案
根据业务需求分两种常见场景处理:
场景1:各个ShotList组件数据完全独立,互不关联
直接将数据状态下沉到ShotList组件内部维护,无需在App层维护公共数据源:
修改后的list.js代码
import React from "react"; const ShotList = () => { // 组件内部维护独立的数据源 const [data,setData] = React.useState([ { name1:"asdsad", key: 0 }, { name1:"asdrsad", key: 1 }, { name1:"asdrsad", key: 2 } ]); const removeData = (targetKey) => { setData(data.filter((value) => value.key !== targetKey)) } return ( <> {data.map((value) => ( <p onClick={() => {removeData(value.key)}} key={value.key}>{value.name1}</p> ))} <p>123</p> </> ); }; export default ShotList;
修改后的app.js代码
import React from 'react'; import './App.css'; import ShotList from "./List" function App() { return ( <div className="App"> <ShotList></ShotList> <ShotList></ShotList> </div> ); } export default App;
场景2:需要保留App层的公共原始数据,各个ShotList的删除仅作用于自身视图
每个ShotList内部维护独立的已删除key集合,仅过滤自身渲染的数据,不修改App层的公共数据源:
修改后的list.js代码
import React from "react"; const ShotList = ({rawData}) => { // 内部维护已删除的key集合,不修改原始公共数据 const [deletedKeys, setDeletedKeys] = React.useState(new Set()); const removeData = (targetKey) => { setDeletedKeys(prev => new Set(prev).add(targetKey)) } // 渲染前过滤掉已删除的项 const showData = rawData.filter(item => !deletedKeys.has(item.key)) return ( <> {showData.map((value) => ( <p onClick={() => {removeData(value.key)}} key={value.key}>{value.name1}</p> ))} <p>123</p> </> ); }; export default ShotList;
修改后的app.js代码
import React from 'react'; import './App.css'; import ShotList from "./List" function App() { // 公共原始数据仅做初始化用,不被子组件修改 const [rawData,setRawData] = React.useState([ { name1:"asdsad", key: 0 }, { name1:"asdrsad", key: 1 }, { name1:"asdrsad", key: 2 } ]); return ( <div className="App"> <ShotList rawData={rawData}></ShotList> <ShotList rawData={rawData}></ShotList> </div> ); } export default App;
额外优化点
- 原代码中map渲染时不要用遍历的index作为key,也不要将index作为删除判断的依据,直接使用数据项自带的key属性可以避免数据顺序变化后出现删除错误的问题
- 组件入参建议解构props命名,避免和内部数据变量命名混淆,提升代码可读性
内容的提问来源于stack exchange,提问作者Jerrin stephen
相关产品推荐
相关产品推荐

