为什么使用immutable
使用immutable创建的数据集合一旦被创建就无法被改变,每次对这个数据集合进行修改都会返回新的值。这点特性对redux这样的偏函数式框架非常重要。
immutable相似的数据集合能够共享他们之间相同的节点,这对于节省内存是非常有好处的。
immutable的边界性问题
- 在React视图里,props其实就来自于Redux维护的全局的state的,所以props中的每一项一定是immutable的;
- 在React视图里,组件自己维护的局部state如果是用来提交到store的,必须为immutable的,否则不强制;
- 从视图层向同步和异步action发送的数据(A/B),必须是immutable;
- Action提交给reducer的数据(C/D),必须是immutable的;
- reducer处理后所得state(E)当然一定是immutable的。
除了向服务端发送数据请求的时候,其他位置,不允许出现toJS的代码。而接收到服务端的数据后,在流转入全局state之前,统一转化为immutable数据。
一句话总结就是在redux中流转的节点,包适流入到action的数据、action流入reducer、reducer流出的数据。而在视图中流转的数据则要看情况而定。
集成immutable到流程中
reducers
我们用redux-immutable提供的combineReducers来处理,他可以将immutable类型的全局state进行分而治之。1
2
3
4
5
6
7import { combineReducers } from 'redux-immutable'
const rootReducer = combineReducers({
routing: routingReducer,
a: immutableReducer,
b: immutableReducer
})
export default rootReducer
initialState
1 | const initialState = Immutable.Map() |
mapStateToProps
1 | const mapStateToProps = (state) => ({ |
immutable基础API更多
原生js转换为immutableData
1 | Immutable.fromJS([1,2]) // immutable的 list |
从immutableData回到JavaScript对象
1 | immutableData.toJS() |
判断两个immutable数据是否一致
1 | Immutable.is(immutableA, immutableB) |
判断是不是map或List
1 | Immutable.Map.isMap(x) |
对象合并(注意是同个类型)
1 | let immutableMaB = immutableMapA.merge(immutableMaC) |
Map的增删查改
查
1 | immutableData.get('a') // {a:1} 得到1。 |
增和改(注意不会改变原来的值,返回新的值)
1 | immutableData.set('a', 2) // {a:1} 得到1。 |
删
1 | immutableData.delete('a') |
List的增删查改
如同Map,不过参数变为数字索引。1
immutableList.set(1, 2)