immutable(不可改变的,永恒不变的)
引入
immutable最重要的是一定要统一好数据类型,控制好存的环节要转成immmutable,还有取得环节 保证视图使用的一直都是 immutable
我们需要什么?需要一个不同内存地址对象,这样视图数据就可以更新
对象深拷贝 JSON.parse(JSON.stringify(obj))
这样做,无差别攻击所有对象不管是否修改到全部转字符串,开辟新地址,这样项目足够庞大是非常耗费性能的,fackboox 专门开发 immutable
对数据进行任何修改或添加删除等操作都会返回新的 Immutable 对象,同时又可避免 deepCopy 把所有节点都复制一遍带来的性能损耗。
immutable是React中非常重要的一环,是facebook专门为React打造
安装
cnpm i immutable -D
const immutable = require('immutable');
浅转换
Map 原生object转Map对象只会转换第一层
immutable.Map({name:'danny', age:18}) //Map { "name": "danny", "age": 18 }
List 原生array转List对象,只会转换第一层
immutable.List([1,2,3,4,5]) //List [ 1, 2, 3, 4, 5 ]
深度转
fromJS 原生js转immutable对象
var obj1={name:'danny', age:18}
var obj2={name:'danny', age:18,info:{say:"我爱北京天安门"}}
immutable.Map(obj1) //Map { "name": "danny", "age": 18 }
immutable.Map(obj2) //Map { "name": "danny", "age": 18, "info": [object Object] }
immutable.fromJS(obj2) //Map { "name": "danny", "age": 18, "info": Map { "say": "我爱北京天安门" } }
将immutable对象转js对象
.toJS(),这个是immutable对象数据类型里面的方法
浅转换
Map.toObject() 纯对象类型转换
List.toArray() 纯数组类型转换
深转换
immutable.toJS () 深度转化,(对象,数组)混合类型都可以转
fromJS({a:1,b:2,info:{say:"我的天"}}).toJS()
任何修改都会生成一个新数据,而不会修改原始数据
immutable_List类型的数据 也使用push
const testArr=immutable.List([1,2,3,5]);
console.log(testArr.push(1));
console.log(testArr);
merge
数据合并
var imA = immutable.fromJS({a:1,b:2});
var imB = immutable.fromJS({c:3,a:100});
imA.merge(imB)
map 循环
Map,List map
原生js对象不能使用map遍历,不推荐 Map类型使用
const alpha = immutable.Map({ a: 1, b: 2, c: 3, d: 4 });
const upperCase = alpha.map((v, k) => k.toUpperCase()).join();//转字符串默认用逗号连接
数组操作
- 返回区别
var arr =[1,2,3];
var arr1=arr.push(1);
console.log(arr1); //原生JS返回长度
const list1 = immutable.List([1, 2])
const list2 = list1.push(3, 4, 5) //返回结果跟js区别 List [ 1, 2, 3, 4, 5 ]
//任何增删改都会生成一个新对象
const list1 = immutable.List([1, 2])
const list2 = list1.push(3, 4, 5)
//immutable 方法
const list3=list2.splice(0,1)
console.log(list3);//List [ 2, 3, 4, 5 ]
list1.concat(list2, list3) //合并
list2.get(0) //读第0个值
对象增删改
任何增删改都会生成一个新对象
增 set
重复key为改
不重复为新增
var Map1 = immutable.fromJS({a:1,b:2,c:{d:3}});
Map1.set("xxx",119) //直接增
Map1.setIn(['c', 'd'], 4).toJS() //深度增
删 delete
var Map1 = immutable.fromJS({a:1,b:2,c:{d:3}});
Map1.delete('a')
Map1.deleteIn(['c', 'd'])
改 update
var Map1 = immutable.fromJS({a:1,b:2,c:{d:3}});
Map1.update('a',function(x){return x+4});
Map1.updateIn(['c', 'd'],function(x){return x+4});
var newMap2=Map1.setIn(["c","xxx"],20).updateIn(["c","xxx"],(x)=>(x+1)); //直接增
console.log(newMap2); //Map { "a": 1, "b": 2, "c": Map { "d": 3, "xxx": 21 } }
查 get
var Map1 = immutable.fromJS({a:1,b:2,c:{d:3}});
//浅查
Map1.get('c')
Map1.get('c').get("d")
//深度查
Map1.getIn(["c","g","y"])
比较
两个immutable对象比较
const map1 = immutable.Map({ a: 1})
const map2 = immutable.Map({ a: 1})
//是否相等
console.log(map1.equals(map2))
//深比较
const obj1={ a: 1 ,test:{num:1,deeptest:{a:0}}};
const obj2={ a: 1 ,test:{num:1,deeptest:{a:0}}};
immutable.fromJS(immutable.fromJS(obj1)).equals(immutable.fromJS(obj2))
reducer使用
import {fromJS} from "immutable"
//转为immutable
const defaultStore=fromJS({
num:0
})
export default (state=defaultStore,action)=>{
// 必需返回一个对象
//state immutable类型
switch (action.type){
case "NUM_ADD":
return state.update("num",(x)=>++x)
}
return state;
}
App
class App extends Component {
render() {
console.log(this.props)
return (
<Fragment>
<GlobalStyle/>
<h1>{this.props.num}</h1>
<button onClick={this.props.handleAdd.bind(this)}>add</button>
</Fragment>
)
}
}
// 状态
const mapStateToProps=(res)=>({
num:res.get("num")
})
//里面必需返回一个对象
const mapDispathToProps=(dispath)=>({
handleAdd(){
var action={
type:"NUM_ADD"
}
dispath(action)
}
})
redux-immutable@4.0.0
解决redux 多库暴露最外层还是js对象问题
//import {createStore,combineReducers} from "redux";
import {createStore} from "redux";
import {combineReducers} from "redux-immutable";
// 多库形式
const store=combineReducers({
indexReducer,
listReducer
})
export default createStore(store);