2017-04-12 92 views
8

我对React和Redux使用Object.assign有些疑惑。在React/Redux中使用Object.assign或Spread运算符?哪一个更好的做法

我看了这个article

它说ES6不支持所有的浏览器,但我已经开始使用它。

我有两个问题:

  1. 是不是一个正确的决定,继续Object.assign
  2. 有什么选择?

我的代码

export const selectDiameter = (scaleData, size) => { 
    return { 
    type: SELECT_DIAMETER, 
    payload: Object.assign({}, scaleData, { 
     diameter: Object.assign({}, scaleData.diameter, { 
      selected_tube_diameter: size, 
      is_clicked: true, 
      audio: Object.assign({}, scaleData.diameter.audio, { 
       is_played: true 
      }) 
     }) 
     }) 
    } 
} 

什么是上面的代码替代?

+0

redux指南特别提到使用[object rest spread transform](https://babeljs.io/docs/plugins/transform-object-rest-spread/)而不是'Object.assign' http://redx .js.org/docs/recipes/UsingObjectSpreadOperator.html –

+0

rest-spread是另一种选择(看起来更好)。无论哪种方式,如果您使用的是ES6,您现在无论如何都需要将其转换为ES5。 –

+0

不相关,但请在代码中使用一些空格,以便清晰。也是无关的,但JS约定使用camelCase,例如'selectedTubeDiameter'而不是蛇'case selected_tube_diameter'。当你只是把东西倒入你控制的空对象时,使用Object.assign没有任何意义。 –

回答

12

终极版的文档建议您使用蔓延运营商的做法,而不是Object.assign

按照文档:

的另一种方法是使用对象传播语法提出 为下一版本JavaScript,它允许您使用传播 (...)运算符以更简洁的方式将一个对象的可枚举属性复制到另一个对象 。对象散布运营商是 概念上类似于ES6阵列蔓延运营商

在您撰写复杂的对象

使用Spread运算符的语法

使用对象传播语法的优势就更加明显了
export const selectDiameter = (scaleData,size) => { 
    return { 
    type: SELECT_DIAMETER, 
    payload: {...scaleData, 
       diameter: { 
          ...scaleData.diameter, 
          selectedTube: size, 
          isClicked: true, 
          audio: { 
           ...scaleData.diameter.audio, 
           isPlayed: true 
          } 
       } 

      } 
    } 
} 

它仍然使用ES6。请参阅Redux docs有关为相同的代码进行配置的更多信息

但是当您处理嵌套数据时。我更喜欢使用immutability-helpers

为您的代码就会像

import update from 'immutability-helpers'; 

export const selectDiameter = (scaleData,size) => { 
    return { 
    type: SELECT_DIAMETER, 
    payload: update(scaleData, { 
     diameter: { 
      selectedTube: { $set: size}, 
      isClicked: { $set: true}, 
      audio: { 
       isPlayed: {$set: true} 
      } 
     } 
    }) 
    } 
} 
1

的替代您发布的代码使用物展开:

export const selectDiameter = (scaleData, size) => ({ 
    type: SELECT_DIAMETER, 
    payload: { 
     ...scaleData, 
     diameter: { 
      ...scaleData.diameter, 
      selected_tube_diameter: size, 
      is_clicked: true, 
      audio: { 
       ...scaleData.diameter.audio, 
       is_played:true 
      } 
     } 
    } 
}); 

我也缩短的身体箭头函数在你的代码中简单地返回对象。

通过使用Babel插件transform-object-rest-spread,可以使用对象休息扩展语法。在

npm install --save-dev babel-plugin-transform-object-rest-spread 

配置它的使用:

这样安装它。babelrc这样的:

{ 
    "plugins": ["transform-object-rest-spread"] 
} 
0

对象蔓延ES7语法,呈现由巴贝尔,Object.assign()的支持是ES6语法,它不以某种浏览器的支持。 这就是为什么你应该使用传播,而不是Object.assign()对象

1

好可能是我是不是很合适,但是这是从丹·阿布拉莫夫(Redux的创建者)

最后,你需要记住, Object.assign是 ES6中的一种新方法,因此它在所有浏览器中都不是本地可用的。你应该使用一个polyfill,或者随Babel一起提供,或者使用一个独立的Object.assign polyfill来使用它,而不会冒着损坏你的网站的风险。

另一个不需要填充的选项是使用不属于ES6的新对象扩展运算符 。但是,对于ES7提议的是 。这是相当受欢迎的,并且它在Babel中启用,如果 您使用第二阶段预设。