immutable

文章目录
  1. 1. immutable.js
  2. 2. immer.js

PureComponent浅比较在判断Object和Array等引用类型时会出错

immutable.js

import { fromJS } from 'immutable';

const data = {
val: 1,
desc: {
text: 'a',
},
content: {
title: 'ha'
}
}

// 将js对象转化为immutable对象
const a = fromJS(data);

// 每次赋值操作都会返回一个新的对象
const b = a.set('val', 2);
console.log(a.get('val')); // 1
console.log(b.get('val')); // 2

// 使用setIn修改a.desc.text
const c = a.setIn(['desc', 'text'], 'b');
console.log(a.get('desc') === c.get('desc')); // false
console.log(a.get('content') === c.get('content')); // true


// 转回js对象
const aa = toJS(a);
const cc = toJS(c);
console.log(aa.content === cc.content); // false
import { Map } from 'immutable';
import { cloneDeep } from 'lodash';


getInitialState() {
return {
// data: { times: 0 }
data: Map({ times: 0 }),
}
},
handleAdd() {
// const data = cloneDeep(this.state.data);
// data.times++;
// this.setState({ data });

this.setState({
data: this.state.data.update('times', v => v + 1)
});

// 简写
this.setState(({data}) => ({
data: data.update('times', v => v + 1)
}));
}
import {is} from 'immutable';

shouldComponentUpdate(nextProps, nextState) {
const thisProps = this.props || {};
const thisState = this.state || {};
nextState = nextState || {};
nextProps = nextProps || {};

if (Object.keys(thisProps).length !== Object.keys(nextProps).length ||
Object.keys(thisState).length !== Object.keys(nextState).length) {
return true;
}

for (const key in nextProps) {
if (!is(thisProps[key], nextProps[key])) {
return true;
}
}

for (const key in nextState) {
if (!is(thisState[key], nextState[key])) {
return true;
}
}
return false;
}

immer.js

[TODO]原理

import produce from 'immer';


// this.setState({
// user: {
// ...this.state.user,
// age: this.state.user.age + 1
// }
// })
// this.setState(prevState => ({
// user: {
// ...prevState.user,
// age: prevState.user.age + 1
// }
// }))


this.setState(
produce(draft => {
draft.user.age += 1
})
)

this.state.draft.user.age++; // error Object.freeze