一、为何要用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;