一、为何要用immutable深拷贝?
1.浅拷贝(浅复制)
//引用赋值-浅复制、浅拷贝
var obj={name:"溜溜球"}var obj2=obj;obj2.name="刘刘球";console.log(obj);//name:"刘刘球"console.log(obj2);//name:"刘刘球"
2.object.assign()一级属性复制,比浅复制多赋值一层,不是真正的深复制
//比浅复制多赋值一层,不是真正的深复制var myobj={name:"六六球",like:["打球","rapper"]}var myobj2={...myobj};myobj2.name="66球";myobj2.like.splice(0,1)console.log(myobj);console.log(myobj2);
3.const obj1 = JSON.parse(JSON.stringify(obj)); 数组,对象都好用的方法(缺点: 不能有undefined)
//json-parse json-stringify
var jsonobj={name:"遛遛",like:["下棋","swage"],
}
var jsonobj2=JSON.parse(JSON.stringify(jsonobj));
jsonobj2.name="66";
jsonobj2.like.splice(0,1);
console.log(jsonobj);
console.log(jsonobj2);
有undefined时被丢弃
//json-parse json-stringify
var jsonobj={name:"遛遛",like:["下棋","swage"],age:undefined
}
var jsonobj2=JSON.parse(JSON.stringify(jsonobj));
jsonobj2.name="66";
jsonobj2.like.splice(0,1);
console.log(jsonobj);
console.log(jsonobj2);
Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享
二、使用
1.安装:npm install immutable
2.mmutable中常用类型(Map,List)
①Map(对象)
import React, { Component } from 'react';
import {Map} from 'immutable';
var obj={name:"六六",age:17
}
var oldImmuObj=Map(obj);
var newmmuObj=oldImmuObj.set( 'name',"66");
console.log(oldImmuObj,newmmuObj);
//1.get获取immutable
console.log(oldImmuObj.get('name'),newmmuObj.get('name'));
//2.immutable转为普通对象
console.log(oldImmuObj.toJS(),newmmuObj.toJS());
②List(数组)
import React, { Component } from 'react';
import { List } from 'immutable';var list=List([1,2,3]);
var list2=list.push([4,5]);
var list3=list.unshift(0);
console.log(list.toJS(),list2.toJS(),list3.toJS());
//push, set, unshift or splice 都可以直接用,返回一个新的immutable对象
toJS():将复杂对象转为普通对象
const deep = Map({ a: 1, b: 2, c: List([ 3, 4, 5 ]) });
console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]
console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }
JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}'
③.map与list案例
1.复杂案例
import React, { Component } from 'react';
import { List,Map } from 'immutable';class update extends Component {state={info:Map({name:"溜溜球",location:Map({provice:"四川",city:"成都"}),favor:List(["读书","看包","写代码"])})}render() {return (<div><button onClick={()=>{this.setState({info:this.state.info.set("name","66球").set("location",this.state.info.get("location").set("provice","广东").set("city","深圳"))})}}>修改</button><div>{this.state.info.get("name")}</div><div>{this.state.info.get("location").get("provice")}-{this.state.info.get("location").get("city",)}</div><div> <ol>{this.state.info.get("favor").map((item,index)=><li key={item}>{item}<button onClick={()=>{this.setState({info:this.state.info.set("favor",this.state.info.get("favor").splice(index,1))})}}>删除</button></li> )}</ol></div></div>);}
}export default update;
2.fromJS()方法将普通对象转为复杂对象,自动加上List和Map.提供了获取方法getIn(),设置新值方法setIn(),回调函数更新updateIn().
const nested = fromJS({ a: { b: { c: [ 3, 4, 5 ] } } });
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } }
const nested2 = nested.mergeDeep({ a: { b: { d: 6 } } });
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
console.log(nested2.getIn([ 'a', 'b', 'd' ])); // 6
//如果取一级属性 直接通过get方法,如果取多级属性 getIn(["a","b","c"]])
//setIn 设置新的值
const nested3 = nested2.setIn([ 'a', 'b', 'd' ], "kerwin");
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: "kerwin" } } }
//updateIn 回调函数更新
const nested3 = nested2.updateIn([ 'a', 'b', 'd' ], value => value + 1);
console.log(nested3);
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }
const nested4 = nested3.updateIn([ 'a', 'b', 'c' ], list => list.push(6));
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }
/** @Author: Spring* @LastEditors: Aidam_Bo* @LastEditTime: 2023-05-29 17:26:15*/
import React, { Component } from 'react';
import { fromJS} from 'immutable';class update extends Component {state={info:fromJS({name:"溜溜球",location:{provice:"四川",city:"成都"},favor:["读书","看包","写代码"]})}componentDidMount() {console.log("fromJS",this.state.info);}render() {return (<div><button onClick={()=>{this.setState({info:this.state.info.set("name","66球").setIn(["location","provice"],"广东").setIn(["location","city"],"深圳")})}}>修改</button><div>{this.state.info.get("name")}</div><div>{this.state.info.getIn(["location","provice"])}-{this.state.info.getIn(["location","city"])}</div><div> <ol>{this.state.info.get("favor").map((item,index)=><li key={item}>{item}<button onClick={()=>{this.setState({info:this.state.info.updateIn(["favor"],(list)=>list.splice(index,1))})}}>删除</button></li> )}</ol></div></div>);}
}export default update;