Reputation: 187
In reducers,we always use Object.assign({},state,newState)
to save a state. But assign()
doesn't support deepcopy,because this method only copy a reference of multi-level object. This is my code in program.
const menuListState={
menuList: {},
menuListLoading:false
}
function getMenuList(state=menuListState,action=defaultAction){
switch(action.type){
//menuList begin
case actions.GET_MENULIST_SUCCESS:
return Object.assign({},state,{
menuList:action.data,
menuListLoading:false
});
default:
return state;
}
}
The property menuList
is a multi-level Object. And when action.data
changes, will state.menuList
be changed immediately before the method assign()
work?
Upvotes: 17
Views: 29790
Reputation: 41
Very interested this thread. HERE is my rough profiling in chrome. largeObj is about 15k chars
let i, t = new Date().getTime();
for(i=0;i<1000;i++) cloneDeep(largeObj)
console.log('clone', new Date().getTime() - t);
t = new Date().getTime();
for(i=0;i<1000;i++) JSON.parse(JSON.stringify(largeObj));
console.log('JSON', new Date().getTime() - t);
And the below is my result. "clone" won
clone 46
JSON 82
clone 42
JSON 87
clone 45
JSON 87
clone 46
JSON 85
clone 44
JSON 86
Upvotes: 1
Reputation: 1360
You can use JSON.stringify
to stringify an object, and use JSON.parse
to parse your result string into an object, you will get your new object same with the one you want to deeply copy.
Example:
let copiedObject = JSON.parse(JSON.stringify(originalObject))
Upvotes: 32
Reputation: 2627
You can do, JSON serialisation,
var clone = JSON.parse(JSON.stringify(oldObjCopy));
but, its not recommended as,
you may lose any Javascript, JSON property like Function
or undefined
.Those get ignored by JSON.stringify
, causing them to be missed on the cloned object.
Date
object results into string
.
instead you can use easiest Lodash
,
import cloneDeep from 'lodash/cloneDeep';
var clone = cloneDeep(oldObjCopy);
Upvotes: 1
Reputation: 1645
You may be interested in cloneDeep form lodash, used as follows:
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
Heres the npm package for just that method.
Upvotes: 13
Reputation: 185
Sure if action.data
is reference types (object, array,...), state.menuList
will be changed immediately when you change action.data
because they reference to the same value. It's just a normal functional of Javascript.
Upvotes: 0