关于React-Native使用immutable(redux环境下)的一点用法
2017-09-25 22:14
1136 查看
Immutable的优点
每次对Immutable对象的操作返回的都是一个新对象,不会出现“篡改行为”
clone行为自下而上,共同部分会被保留,自己以上的节点才会被操作,性能更好
api丰富
延迟操作等高端姿势
为什么性能快,因为用了hash maps tries和vector tries传送门:http://en.wikipedia.org/wiki/Hash_array_mapped_trie
http://hypirion.com/musings/understanding-persistent-vector-pt-1
通常在redux下面需要考虑深复制和浅复制的差别,所以我们引入Immutable, 好处就不多说,直接开始。
还有很多高端操作,以及作者给我们提供的List、Map、Stack、Set、Record
等等高端货请大家自行去翻API吧传送门:http://facebook.github.io/immutable-js/docs/#/
combineReducers的切换
我们之前combineReducers用的是Redux提供的,但是它只能处理原生JS,所以我们需要引入redux-immutable,它提供的combineReducers可以处理Immutable数据
每个Reducer的初始化数据也应该采用Immutable数据
与服务端数据的交互在第获取一时间转换为Immutable数据,在发送第一时间转化为原生数据
这里需要注意以下两点:
如果使用安卓模拟器,且使用localhost的数据,需要直接填写localhost的ip地址。因为模拟器有自己的localhost ip,如果直接用localhost就指向了它提供的地址,而不是本机的地址了
如果使用iOS模拟器,其请求的是http协议的地址,需要在info.plist开启对http的支持,如下:
因为Persistent data structire,Reducer返回的数据不用新建一个对象了
shouldComponentUpdate可以进行统一处理了
函数的传递方式需要注意
如果每次render时都是重新声明的函数,则其对比会有问题,因为is()内部对函数的对比是基于ValueOf的,所以将下面的第一种方式改为第二种方式:
还有一些优缺点:
优
能便利的进行时间溯洄,便于状态的把控与调试
结构共享,节约内存
并发安全
能抽象出统一的对比函数
Model与View耦合度不高
缺
有学习成本
容易与原生函数混淆,并且原生函数一旦重写可能会导致问题
资源大小增加
跨页面数据同步方式会有变动,之前页面间进行引用传递,在B页面进行的修改会自动呈现到A页面,但是现在是Persistent data structire,因此B页面的改动A页面无感,需要特殊的触发机制来进行状态同步
因为并非原生的数据结构,所以像解构这种用法需要引入特殊的库后才能使用
参考:
React.js Conf 2015 - Immutable Data and React
Optimizing Performance
Immutable.js
Immutable.js 以及在 react+redux 项目中的实践
Immutable 详解及 React 中实践
从 React 的组件更新谈 Immutable 的应用
基于React Native及Redux的Immutable.js引入
作者:江湖人称_赫大侠
链接:http://www.jianshu.com/p/638880152889
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
每次对Immutable对象的操作返回的都是一个新对象,不会出现“篡改行为”
clone行为自下而上,共同部分会被保留,自己以上的节点才会被操作,性能更好
api丰富
延迟操作等高端姿势
为什么性能快,因为用了hash maps tries和vector tries传送门:http://en.wikipedia.org/wiki/Hash_array_mapped_trie
http://hypirion.com/musings/understanding-persistent-vector-pt-1
通常在redux下面需要考虑深复制和浅复制的差别,所以我们引入Immutable, 好处就不多说,直接开始。
API简单案例
romJS()
将JS对象和数组转换为不可变Map和Listlet map1 = Immutable.fromJS(map); let map2 = map1.set('a', 4); console.log('---> map1 ' + map1.get('a')); console.log('---> map2 ' + map2.get('a')); //结果 ---> map1 1 ---> map1 4
toJS()
将Immutable数据转换为原生JSset()
const originalList = List([ 0 ]); // List [ 0 ] originalList.set(1, 1); // List [ 0, 1 ] List().set(50000, 'value').size; // 50001
setIn(): 进行深度赋值
const list = List([ 0, 1, 2, List([ 3, 4 ])]) list.setIn([3, 0], 999); // List [ 0, 1, 2, List [ 999, 4 ] ]
get()
const list = List([ 0 ]); let value = list.get(0); // 0
getIn(): 进行深度取值
const list = List([ 0, 1, 2, List([ 3, 4 ])]); let value = list.getIn([3, 0]); // 3
is()
比较两个对象是否相等let map1 = Immutable.fromJS(map); let map2 = Immutable.fromJS(map); console.log('---> map1 == map2 ' + (map1 === map2)); console.log('---> map1 == map2 ' + Immutable.is(map1, map2)); //结果 ---> map1 == map2 false ---> map1 == map2 true //因为每次返回的是不同对象,就算值完全相等,也不相等
isImmutable()
判断是否为Immutable对象console.log('---> isImmutable([]) ' + isImmutable([])); console.log('---> isImmutable({}) ' + isImmutable({})); console.log('---> isImmutable(Map()) ' + isImmutable(Map())); console.log('---> isImmutable(List()) ' + isImmutable(List())); //结果 ---> isImmutable([]) false ---> isImmutable({}) false ---> isImmutable(Map()) true ---> isImmutable(List()) true
还有很多高端操作,以及作者给我们提供的List、Map、Stack、Set、Record
等等高端货请大家自行去翻API吧传送门:http://facebook.github.io/immutable-js/docs/#/
直接使用
这是一点使用方法,导入后,在更新的生命周期进行对比,如果没有改变的item是不会刷新的,这样很好的提高了整体列表的性能。shouldComponentUpdate(nextProps, nextState) { let rusult1 = !Immutable.is(Immutable.Map(this.props.item[0]), Immutable.Map(nextProps.item[0])); let rusult2 = !Immutable.is(Immutable.Map(this.props.item[0]), Immutable.Map(nextProps.item[0])); return rusult1 || rusult2; }
在RN+Redux的项目中使用
在第一点中我们分析了遇到的优化点,在第二点中我们讲解了能进行优化的工具,现在我们来进行具体的优化。combineReducers的切换
我们之前combineReducers用的是Redux提供的,但是它只能处理原生JS,所以我们需要引入redux-immutable,它提供的combineReducers可以处理Immutable数据
import {createStore, applyMiddleware, compose} from 'redux'; import {combineReducers} from 'redux-immutable'; ... export default (data = Immutable.Map({})) => { const rootReducer = combineReducers({ route: routeReducer, modules: combineReducers(reducers) }); return createStore(rootReducer, data, middleware); };
每个Reducer的初始化数据也应该采用Immutable数据
const initialState = Immutable.Map({ dataList: Immutable.List([]), count1: 0 });
与服务端数据的交互在第获取一时间转换为Immutable数据,在发送第一时间转化为原生数据
return fetch(url).then((res) => { return res.json(); }, (er) => {console.log(er);}).then((data) => { data = Immutable.fromJS(data || {}); dispatch({ type: GETDATA_END, payload: { dataList: data.get('data') } }); }, (error) => { console.log(error); dispatch({ type: GETDATA_BEGIN }); });
这里需要注意以下两点:
如果使用安卓模拟器,且使用localhost的数据,需要直接填写localhost的ip地址。因为模拟器有自己的localhost ip,如果直接用localhost就指向了它提供的地址,而不是本机的地址了
如果使用iOS模拟器,其请求的是http协议的地址,需要在info.plist开启对http的支持,如下:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
因为Persistent data structire,Reducer返回的数据不用新建一个对象了
[GETDATA_END]: (state, action) => { const {dataList} = action.payload; return state.set('dataList', dataList); },
shouldComponentUpdate可以进行统一处理了
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 (!Immutable.is(thisProps[key], nextProps[key])) { return true; } } for (const key in nextState) { if (!Immutable.is(thisState[key], nextState[key])) { return true; } } return false; }
函数的传递方式需要注意
如果每次render时都是重新声明的函数,则其对比会有问题,因为is()内部对函数的对比是基于ValueOf的,所以将下面的第一种方式改为第二种方式:
<TouchableOpacity onPress={() => this.addCount()} style={Style.btnContainer}> <Text style={Style.btnWord}>addCount</Text> </TouchableOpacity> <TouchableOpacity onPress={this.addCount} style={Style.btnContainer}> <Text style={Style.btnWord}>addCount</Text> </TouchableOpacity>
还有一些优缺点:
优
能便利的进行时间溯洄,便于状态的把控与调试
结构共享,节约内存
并发安全
能抽象出统一的对比函数
Model与View耦合度不高
缺
有学习成本
容易与原生函数混淆,并且原生函数一旦重写可能会导致问题
资源大小增加
跨页面数据同步方式会有变动,之前页面间进行引用传递,在B页面进行的修改会自动呈现到A页面,但是现在是Persistent data structire,因此B页面的改动A页面无感,需要特殊的触发机制来进行状态同步
因为并非原生的数据结构,所以像解构这种用法需要引入特殊的库后才能使用
参考:
React.js Conf 2015 - Immutable Data and React
Optimizing Performance
Immutable.js
Immutable.js 以及在 react+redux 项目中的实践
Immutable 详解及 React 中实践
从 React 的组件更新谈 Immutable 的应用
基于React Native及Redux的Immutable.js引入
作者:江湖人称_赫大侠
链接:http://www.jianshu.com/p/638880152889
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关文章推荐
- React Native 学习笔记十九(关于开发环境)
- redux在react-native中的使用
- react native 学习笔记 2016_1223 (环境,箭头函数,state设置,图片使用等)
- React Native ref高级用法&&setNativeProps使用
- [React Native]Redux的基本使用方式
- React Native 学习笔记二十(关于ListView的使用)
- React Native 学习笔记四(关于state的使用)
- 使用Subline开发React-Native编辑器环境搭建
- 在react-native中使用redux
- 使用immutable和react-immutable-render-mixin优化React Native视图渲染
- redux在react-native上使用(五)--redux-actions使用
- linux环境下调试嵌入式设备时出现Aborted、segmentation fault、卡死的问题以及关于指针使用的一点想法
- redux在react-native上使用(一)--加入redux
- React native Listview 使用react-redux时候更新不起效果
- Mac React-Native环境搭建及使用
- redux在react-native上使用(二)--加入redux-saga
- React Native 学习笔记五(关于样式的使用)
- 使用WebStrom开发设置ReactNative关于JSX中的XML部分的智能提示插件的安装办法
- React Native 开发环境安装和配置使用报错: -bash: react-native: command not found
- 在react-native中使用redux