Use Object.assign or Spread Operator in React/Redu

2019-01-08 18:14发布

问题:

I have some confusion about using Object.assign for React and Redux.

I read this article.

It says ES6 Does not supported by all browsers but I have started using it.

I have two questions:

  1. Is it the right decision to continue with Object.assign?
  2. What is the alternative?

My Code

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
             })
         })
      })
   }
}

What is the alternative for the above code?

回答1:

Redux docs recommends you to use the spread operator approach instead of the Object.assign

As per the docs:

An alternative approach is to use the object spread syntax proposed for the next versions of JavaScript which lets you use the spread (...) operator to copy enumerable properties from one object to another in a more succinct way. The object spread operator is conceptually similar to the ES6 array spread operator

The advantage of using the object spread syntax becomes more apparent when you're composing complex objects

Using the Spread operator syntax

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

             }
   }
}

It still uses ES6. See the Redux docs for more info on configuring your code for the same

However when you are dealing with the nested data. I prefer to use immutability-helpers

For your code it will be like

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}
            }
         }
    })
   }
}


回答2:

The alternative to the code you posted is using object spreading:

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
            }
        }
    }
});   

I have also shortened the body of the arrow function in your code to simply returning the object.

You can use the object rest spread syntax by using the Babel plugin transform-object-rest-spread.

Install it like this:

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

Configure its use in your .babelrc like this:

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


回答3:

Ok may be I was not really right but this is from Dan Abramov (redux creator)

Finally, you need to remember that Object.assign is a new method in ES6, so it is not natively available in all the browsers. You should use a polyfill, either the one that ships with Babel or a standalone Object.assign polyfill, to use it without risking crashing your website.

Another option that doesn't require a polyfill is to use the new object spread operator, which is not part of ES6. However, it is proposed for ES7. It is fairly popular, and it is enabled in Babel if you use the stage two preset.



回答4:

Object spread is ES7 syntax, render supported by Babel, Object.assign() is ES6 syntax, it not support in some browser. That's why you should use Object spread instead of Object.assign()