ThiagoSun
ThiagoSun

Reputation: 187

Deepcopy in React

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

Answers (5)

tao.wang.pro
tao.wang.pro

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

passion
passion

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

Ashish Kamble
Ashish Kamble

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

Jemar Jones
Jemar Jones

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

Caojs
Caojs

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

Related Questions