React中导入的公共cols配置被TableLoader修改,如何保留原始未变更值?
问题根源
ES 模块的导出是引用绑定,你在Columns.js中导出的cols是固定的引用,所有导入该对象的文件拿到的都是同一个内存地址的对象。而你的TableLoader直接修改了传入cols内部的列对象属性(col.Cell),属于直接修改原引用的内容,因此后续所有使用该引用的地方拿到的都是修改后的值。
你之前用展开运算符无效的原因是只做了浅拷贝:仅拷贝了外层的数组/对象结构,内部的每一项列配置还是和原cols共享引用,修改col.Cell仍然会影响原数据。
可行解决方案
方案1:修改
Columns.js导出逻辑(最稳妥)
改为导出一个返回列配置的函数,每次调用都会生成全新的列配置对象,完全避免引用共享:// Columns.js 修改后代码 export default () => [ {key1:val1}, {key2:val2}, // 其余列配置 ]组件中使用时每次调用获取新的配置即可:
// Widget.js 中使用 import getCols from './Columns'; export default function Widget(){ const cols = getCols() const {data,error,loading} = useQuery(//某查询语句) if(loading)return (<TableLoader cols={getCols()}/>); return (<Table cols={cols} data={data}/>) }方案2:修改TableLoader逻辑(符合React最佳实践)
组件不应该直接修改传入的props,在TableLoader内部先拷贝一份cols再做修改:// TableLoader 内部修改 export default function TableLoader({cols}){ // 对每一项列配置做浅拷贝,断开和原对象的引用关联 const clonedCols = cols.map(col => ({...col})) clonedCols.map((col)=>col.Cell = (<SomeComponent />)); return <Table cols={clonedCols} data={[{}]}> }如果列配置中存在多层嵌套属性,可以用
structuredClone做全量深拷贝。方案3:传入TableLoader前拷贝列配置
不需要改动现有其他逻辑,仅在传值给TableLoader时做拷贝即可:if(loading)return (<TableLoader cols={cols.map(col => ({...col}))}/>);
内容的提问来源于stack exchange,提问作者Yash Tailor
相关产品推荐
相关产品推荐

