繁体   English   中英

在react / redux中,在商店prop上调用map()可在商店本身中编辑prop

In react/redux, calling map() on a store prop edits the prop in the store itself

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我有一个连接到Redux存储的组件,该组件接收一个prop并将其传递给子组件。

在子组件中,我以这种方式在render()方法中详细说明了这个道具

let dataForFlatList = [].concat.apply([], [].concat.apply([], this.props.internalData.map( a => {
   if(a.hasOwnProperty("components")){ 
      a.components[a.components.length-1].lastItem = true
   } else {
      a.dayData.lastItem = true
   } 
   return Object.values(a)
})));

为了清楚起见,Redux商店中的该道具具有以下结构:

[
   {
      dailyData: {
         date: .....
         steps: .....
      },
      components: [ {...}, {...}, {...}, {...}, {...} ...]
   },
   {
      dailyData: {
         date: .....
         steps: .....
      },
      components: [ {...}, {...}, {...}, {...}, {...} ...]
   },
   {
      dailyData: {
         date: .....
         steps: .....
      }
   }
   :::
]

因此,我想做的是将一个属性lastItem添加到components数组中的最后一个对象; 或者,如果不存在componentslastItem添加到对象dailyData 最后,只有一系列concat()才能获得没有嵌套对象的单个数组。

该代码有效,但是这里的一个奇怪的事实是,当我在this.props.internalData上调用map()函数时,商店internalData的prop internalData也被编辑了。

您能帮助您理解为什么会发生吗?

谢谢

1 个回复

Javascript通过引用传递对象。 这意味着,如果克隆对象(所谓的“浅克隆”),则实际上会更改主对象引用,但嵌套属性保持不变。 当您map对象数组或调用Object.assign({}, /.../)时,就会发生这种情况。

因此,当您像a.dayData.lastItem = true那样更改a.dayData.lastItem = true ,实际上是在更改原始属性。 Map将返回克隆的对象,但是此特定分配更改了原始属性的引用值。

为了解决它,您有多种方法:

  1. 克隆整个对象和每个属性(深层克隆)
  2. 不要更改属性,而只是传递一个新值(在每次map迭代中构造一个新对象);

另外,摆脱这些多个[].concat.apply ,可能不需要它们:)

解决方案:

1.您可以尝试使用_.cloneDeephttps : _.cloneDeep

// Inside your map
const clonedA = _.cloneDeep(a);

if(clonedA.hasOwnProperty("components")){ 
   clonedA.components[clonedA.components.length-1].lastItem = true
} else {
   clonedA.dayData.lastItem = true
} 

return clonedA;

但是要警告! 对于大型物体,它可能非常慢(它必须遍历所有结构)。

2.您可以尝试像这样传递新值:

if(a.hasOwnProperty("components")){ 
   // We use empty slice to clone the array
   const clonedComponents = components.slice();
   const lastArrayElement = clonedComponents[clonedComponents.length-1];
   clonedComponents[clonedComponents.length - 1] = Object.assign({}, lastArrayElement, { lastItem: true });

   return Object.assign({}, a, { components: clonedComponents});
} else {
   // Note empty object as the first param - we also return completely new value
   return Object.assign({}, a, { dayData: { lastItem: true } });
} 
return Object.values(a);

映射对象时,如果我知道对象的状态,我仍然更喜欢使用_.cloneDeep_.merge (不要忘记使用{}作为第一个参数调用Object.assign !)。对性能有重大影响。

对于您的情况,我建议遵循我的第二条建议-只需在数据结构的每个级别上创建新对象。 我还建议将这些操作转移给助手,因为您会看到代码变得相当复杂且有些丑陋。

1 在prop中调用React-Redux操作无法提供所需的结果

我正在实现一个处理redux动作以添加注释的组件,但是它不起作用。不会生成错误 我尝试从代码中的其他区域调用道具,但这似乎不起作用。addComment Action应该添加在DishDetails注释部分中呈现的注释,但是不进行任何添加。 ActionTypes.js Ac ...

2 使用map()遍历React中的嵌套Prop

我目前正在使用react渲染一个名为area的道具,如下所示: 更新2- 这工作 : 输出: 结合地图,这个工程 输出: 但是当我包含{this.renderCountries()} ,它什么也不会输出,这就是为什么我无法获得建议的原因。 在 ...

3 在 React 中通过 map 方法传递 prop

我需要映射一个数组来输出一堆组件。 我遇到的困难是将函数作为道具传递 - 它看起来像这样: ...但我无法从地图访问 myFunction。 我知道我可以使用上下文,但是我如何使用道具来实现这一点? ...

4 prop函数中的React - prop函数

我正试图在我的一个组件的另一个道具中执行道具。 基本上我必须等待一些数据从API返回,然后我想执行下一个道具。 这是我的组件2道具代码: 不确定这是否是React开始时的正确方法? 如果是这样,那么不确定为什么道具没有开火...... ...

6 React-Redux:如何使用异步调用中的数据填充加载时的组件的prop?

我有这个自动完成组件,它需要一个术语数组作为dataSource属性。 我要输入的数据驻留在公共API中,我已经按照此处的教程操作,以获取以下代码。 但是本教程(以及其他许多教程)介绍了如何将这些动作绑定到事件,而我想用页面加载数据填充此道具。 我将如何去做? actions.js ...

8 prop参数在React中从哪里来?

在react中,您可以声明一个函数或类组件,并在其中使用prop对象以使您的代码更可重用。 但是我似乎无法弄清楚prop参数本身来自何处。 要么 然后您可以创建如下实例: 在这两个示例中,我似乎都无法理解props对象的来源。 ...

2019-06-08 06:13:48 1 28   reactjs
9 Redux没有在商店更新上调用mapStateToProps

更新状态时请勿使用push 。 使用concat 我面临这个非常奇怪的问题,请考虑使用减速器: 上面的代码未在我的组件内调用mapStateToProps 。 但是,像下面这样修改上面的reducer会调用mapStateToProps : 要么 在两种情况下, ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM