学过React Native的都知道,RN的UI是根据相应组件的state进行render的,而页面又是由大大小小的组件构成,导致每个组件都必须维护自身的一套状态,因此当页面复杂化的时候,管理state会相当吃力的。而redux提供了一套机制来组织管理整个应用状态。

Redux有三部分组成:store,action,reducer。

store:维护全局的state,以及将action和reducer结合起来。

action:用来传递state的信息。(比如:我们在action中处理登陆操作,将返回的user对象传递给对应的reducer.)

reducer:reducer是简单的处理函数,通过传入旧的state和指示操作的action来更新state,从而达到页面的刷新。

下面通过一个简单的例子来集成下。

首先安装相关库:

安装redux:npm install --save redux

安装redux绑定库:npm install --save react-redux

安装开发者工具:npm install --save-dev redux-devtools

安装异步action构造器:npm install --save redux-thunk

在集成之前熟悉下一般基于Redux的目录结构:

  1.  
.
├── src #开发目录
| |
| ├──constants #ActionTypes和Urls
| |
| ├──actions #actions的文件
| |
| ├──components #内部组件
| |
| ├──containers #容器组件
| |
| ├──reducers #reducer文件
| |
| ├──stores #store配置文件
| |
| └──utils #工具
|
├── node_modules #包文件夹
├── .gitignore
├── index.js #入口文件
└── package.json

(如果你之前不了解Redux的话,或许会比较蒙圈,但不要紧,跟着流程多走几遍,试着推敲先分析下流程,慢慢就理解了)

/*************************************store*************************************/

1.首先创建全局的store。(一般在stores文件中写个配置文件)

  1. 'use strict';
  2. import { createStore, applyMiddleware ,combineReducers} from 'redux';
  3. import thunk from 'redux-thunk';//引入异步操作
  4. //引入所有的reducers,切记要在index.js封装下.
  5. import * as reducers from '../reducers';
  6. const middlewares = [thunk];
  7. const createSoreWithMiddleware=applyMiddleware(...middlewares)(createStore);
  8. //配置store信息
  9. export default function configureStore(initialState){
  10. //将reducer组合起来
  11. const reducer=combineReducers(reducers);
  12. //创建store
  13. const store=createSoreWithMiddleware(reducer,initialState);
  14. return store;
  15. }

简单讲解下:

首先引入该APP中所有的reducer,根据上面的目录结构,我们把所有的reducer放入到reducers文件中,切记要加入个index.js进行配置.上面很多都是固定格式,暂时先不分析为什么,做的目的就是返回一个全局的store.

store的应用(这里的APP就是我们应用的最顶层组件)。

  1. import React, { Component } from 'react';
  2. import {Provider} from 'react-redux';
  3. import App from './containers/app';
  4. import configureStore from './store/configureStore';
  5. const store=configureStore();//获取store
  6. export default class Root extends Component{
  7. render(){
  8. return(
  9. <Provider store={store}>
  10. <App/>
  11. </Provider>
  12. );
  13. }
  14. }

App组件其实可以把所有的页面加入到这里,全局进行控制(官方F8是这么操作的)。不过这里暂时先不这样处理,关于navigator的push,pop操作还是放到对应的页面进行处理,更符合我们的原生开发逻辑。

简单看下store中结构:

/*************************************action*************************************/

创建登陆对应的action:

  1. import * as types from './types';
  2. import {Alert}from 'react-native';
  3. //登陆(登陆操作属于耗时操作,所以需要异步执行,这里采用dispatch分发)
  4. export function login(user){
  5. return dispatch=>{
  6. //登陆中,派遣给LOGIN_ING
  7. dispatch({type:types.LOGIN_ING});
  8. let result=fetch('http://www.baidu.com')
  9. .then((res)=>{
  10. //延时2s为了模拟效果
  11. setTimeout(()=>{
  12. if(user.phone=='15221850400'&&user.password=='123456'){
  13. dispatch({type:types.LOGIN,user:user});
  14. }else{
  15. //这里分发的是action
  16. Alert.alert('用户名或密码错误');
  17. dispatch(error());
  18. }
  19. },1000);
  20. }).catch((err)=>{
  21. alert(err);
  22. dispatch({type:types.LOGIN_ERROR});
  23. })
  24. }
  25. }
  26. function error(){
  27. return {
  28. type:types.LOGIN_ERROR
  29. };
  30. }
  31. //登出(由于登出操作一般都只是清空一些数据,不需要异步执行直接返回就可以了,)
  32. export function logout(){
  33. return {
  34. type:types.LOGOUT,
  35. };
  36. }

逻辑还算简单,就只是做个用户名,密码判断,但或许会问dispatch是个什么玩意,哪来的呢,其实上面我们也截图出来了,这个方法是我们创建全局store中的方法。

至于action正常的应该只是一个含有type的json对象,但是为了扩展性,一般会写成函数的形式,俗称action creator如上面的logout方法.

至于login方法由于需要网络操作,固然是异步的,就好比我们原生开发的时候请求API的操作一般都会丢到一个线程中,通过Handler消息机制来渲染UI.

dispatch({type:types.LOGIN_ING}):根据相应的action来进行调用对应reducer方法。

/*************************************reducer*************************************/

接着我们看下最后一个reducer:

  1. import * as types from '../actions/types';
  2. const initialState={
  3. isLoggedIn:false,//登陆状态
  4. user:{},
  5. status: null,//登陆操作状态 ‘done’:已登陆,'doing':正在登陆,null:没有登陆
  6. };
  7. //reducer处理函数更新state,渲染UI(主要根据传入旧的state,)
  8. export default function user(state=initialState,action={}){
  9. switch(action.type) {
  10. case types.LOGIN:
  11. return{
  12. ...state,
  13. isLoggedIn:true,
  14. user:action.user,
  15. status: 'done',
  16. }
  17. break;
  18. case types.LOGIN_ING:
  19. return {
  20. ...state,
  21. isLoggedIn:false,
  22. status: 'doing',
  23. }
  24. break;
  25. case types.LOGIN_ERROR:
  26. console.log('types.LOGIN_ERROR...');
  27. return{
  28. ...state,
  29. isLoggedIn: false,
  30. status: null,
  31. };
  32. break;
  33. case types.LOGOUT:
  34. return {
  35. ...state,
  36. isLoggedIn:false,
  37. status:null,
  38. }
  39. break;
  40. //切莫忘记default返回值
  41. default:
  42. return state;
  43. }
  44. }

reducer其实就是根据一系列action的处理函数,好比我们在前面action中返回的有LOGIN,LOGIN_ING,LOGIN_ERROR等状态,然后调用reducer根据不同的type返回当前最新的state,然后再render ui。

/*************************************connect*************************************/

redux的三部分至此就操作完毕,但如果进行链接起来呢,这里就用到connect组件,connect是将某一个组件(这里一般指一个页面)和store链接起来,目的就是获取当前页面所需的state以及dispatch方法。(从全局state中获取这个页面需要的数据然后以props的形式传递给当前页面。)

  1. import React, { Component } from 'react';
  2. import {
  3. StyleSheet,
  4. TextInput,
  5. Text,
  6. View,
  7. TouchableHighlight,
  8. ActivityIndicator,
  9. } from 'react-native';
  10. import {connect} from 'react-redux';//将我们的页面和action链接起来
  11. import {bindActionCreators} from 'redux';//将要绑定的actions和dispatch绑定到一起
  12. import * as actionCreators from '../actions/loginActions';//导入需要绑定的actions
  13. import Modal from 'react-native-modalbox';
  14. import Home from './home';
  15. /**
  16. 登陆页面
  17. **/
  18. class Login extends Component{
  19. constructor(props){
  20. super(props);
  21. this.state={
  22. }
  23. this.login=this.login.bind(this);
  24. this.onChangePhone=this.onChangePhone.bind(this);
  25. this.onChangePswd=this.onChangePswd.bind(this);
  26. }
  27. onChangePhone(text){
  28. this.setState({'phone':text,});
  29. }
  30. onChangePswd(text){
  31. this.setState({'password':text,});
  32. }
  33. login(){
  34. if(!this.state.phone||!this.state.password){
  35. alert('用户名或密码不能为空!');
  36. }else{
  37. this.refs.modal.open();//loading 状态
  38. this.props.actions.login({'phone':this.state.phone,'password':this.state.password});//dispath 登陆
  39. }
  40. }
  41. //该方法首次不会执行,如果返回false,则reduer不会执行,,
  42. shouldComponentUpdate(nextProps,nextState){
  43. const {isLoggedIn,navigator}=nextProps;
  44. if(isLoggedIn){
  45. this.setState({phone:'',password:''});
  46. navigator.push({
  47. component:Home,
  48. name:'Home',
  49. });
  50. }
  51. return true;
  52. }
  53. render(){
  54. console.log('render...');
  55. return(
  56. <View style={{flex:1}}>
  57. <View style={{padding:20,marginTop:50}}>
  58. <View style={styles.item}><Text style={{width:70}}>手机号码</Text>
  59. <TextInput
  60. style={styles.input}
  61. onChangeText={this.onChangePhone}
  62. placeholder='请输入手机号码'
  63. value={this.state.phone}
  64. />
  65. </View>
  66. <View style={styles.item}>
  67. <Text style={{width:70}}>密码</Text>
  68. <TextInput
  69. style={styles.input}
  70. onChangeText={this.onChangePswd}
  71. placeholder='请输入密码'
  72. password={true}
  73. value={this.state.password}
  74. />
  75. </View>
  76. <TouchableHighlight style={styles.button}
  77. underlayColor='#000000' onPress={this.login}>
  78. <Text style={{fontSize:16,color:'#fff'}}>登陆</Text>
  79. </TouchableHighlight>
  80. </View>
  81. <Modal
  82. style={styles.modal}
  83. ref='modal'
  84. isOpen={this.props.status=='doing'?true:false}
  85. animationDuration={0}
  86. position={"center"}
  87. >
  88. <ActivityIndicator
  89. size='large'
  90. />
  91. <Text style={{marginTop:15,fontSize:16,color:'#444444'}}>登陆中...</Text>
  92. </Modal>
  93. </View>
  94. );
  95. }
  96. }
  97. const styles =StyleSheet.create({
  98. item:{
  99. flex:1,
  100. flexDirection:'row',
  101. alignItems:'center',
  102. height:50,
  103. borderBottomColor:'#ddd',
  104. borderBottomWidth:1,
  105. },
  106. input:{
  107. flex:1,
  108. fontSize:14,
  109. },
  110. button:{
  111. backgroundColor:'#1a191f',
  112. height:50,
  113. marginTop:40,
  114. justifyContent:'center',
  115. alignItems:'center'
  116. },
  117. modal: {
  118. justifyContent: 'center',
  119. alignItems: 'center',
  120. width:150,
  121. height:150,
  122. borderRadius:10,
  123. },
  124. });
  125. //根据全局state返回当前页面所需要的信息,(注意以props的形式传递给Login)
  126. function mapStateToProps(state){
  127. return{
  128. isLoggedIn:state.user.isLoggedIn,
  129. status:state.user.status,
  130. };
  131. }
  132. //返回可以操作store.state的actions,(其实就是我们可以通过actions来调用我们绑定好的一系列方法)
  133. function mapDispatchToProps(dispatch){
  134. return {
  135. actions: bindActionCreators(actionCreators, dispatch)
  136. };
  137. }
  138. //链接起来
  139. export default connect(mapStateToProps,mapDispatchToProps)(Login);

上面的代码不用仔细看,主要是尾部的部分,

mapStateToProps方法:根据全局state返回当前页面所需的数据然后以props的形式传递给当前页面(Login)。

mapDispatchToProps:该方法就是将dispatch和当前页面引入的actionCreators绑定在一起,然后就可以轻松调用。

如:login方法中的:

this.props.actions.login({'phone':this.state.phone,'password':this.state.password});//dispath 登陆

这样整体集成就完毕了,这里简单总结下:

1.首先我们创建全局的store(基于所有的reducer)在APP最外层引用,然后我们创建action(可以根据页面或者某种类别来定义)。接着我们创建reducer(可以设计成跟action一一对应)。最后通过connect将它们和页面链接起来,至于action和reducer的内容,可以等页面编辑OK后再进行设计。

2.执行简单流程:在页面中首先调用对应action方法(传递参数)--->执行相应的业务逻辑,然后调用dispatch(action)(将结果以action的形式传递给reducer)--->在reducer中根据type字段然后返回最新的state,然后在进行render具体的ui。

引用原文:https://blog.csdn.net/jj120522/article/details/52071469

可以参考:https://www.jianshu.com/p/4139babc6d5e

写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!

如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!

React Native集成Redux框架讲解与应用的更多相关文章

  1. Angular团队公布路线图,并演示怎样与React Native集成

    本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2015/06/angular-2-react-native-roadmap 前不久在旧 ...

  2. 将React Native集成至Android原生应用

    将React Native集成至Android原生应用 Android Studio 2.1 Preview 4生成的空项目 react-native 环境 0.22.2 初次编译后apk有1.1M, ...

  3. [RN] React Native 使用 Redux 比较详细和深刻的教程

    React Native 使用 Redux 比较详细和深刻的教程 React Native 使用 Redux https://www.jianshu.com/p/06fc18cef56a http:/ ...

  4. 一次掌握 React 与 React Native 两个框架

    此系列文章将整合我的 React 视频教程与 React Native 书籍中的精华部分,给大家介绍 React 与 React Native 结合学习的方法. 1. 软件开发语言与框架的学习本质 我 ...

  5. 将React Native 集成进现有OC项目中(过程记录) 、jsCodeLocation 生成方式总结

    将RN集成到现有OC项目应该是最常见的,特别是已经有OC项目的,不太可能会去专门搞个纯RN的项目.又因为RN不同版本,引用的依赖可能不尽相同,所以特别说明下,本文参考的文档是React Native ...

  6. react native 之 redux 使用套路

    redux是什么?他是一个state容器 redux的运作方式是怎样的? 接入方式: 1. npm install 下列内容: npm install --save redux npm install ...

  7. react native 之 redux

    第一章  认识redux 说的通俗且直白一点呢,就是redux提供了一个store,独立的一个内存区,然后放了一些state,你可以在任何component中访问到state,这些state要更改怎么 ...

  8. react native 集成react navigation报错

    集成后出现:“Invalid escape sequence at line 1 column 29 path $[0].name”的错误. 解决办法:

  9. React Native使用Redux总结

    1>npm安装redux: "react-redux": "^5.0.5", "redux": "^3.7.1", ...

随机推荐

  1. vue-infinite-scroll 自动加载

    初次上手vue开发 笑话百出,各种麻爪 在实现上拉加载的时候用的是mint-ui里面的 infinite-scroll 结果在使用的时候不停的自动加载,后来查询了相关资料 原来是控件识别只要没有铺满全 ...

  2. github删除已经push到服务器上的commit的方法

    使用两条指令: git reset --hard <commit_id> git push origin HEAD --force 其中commit_id是你想回到的commit的id(即 ...

  3. Oracle 的安全保障 commit &checkpoint

    Oracle 的安全 commit &checkpoint commit ---lgwr 事务相关的操作,保证事务的安全. commit标志着事务的结束.意味着别人对你事务操作的结果可见. c ...

  4. JavaScript 学习(3)核心对象

    ##JavaScript 学习 3 1.核心对象 1.1 String对象 声明和生成 var myString="Hello"; var myString=new String( ...

  5. 【转】windows 下 goprotobuf 的安装与使用

    1. 安装 在网上看了很多教程,都提到要安装 protoc 与 protoc-gen-go,但通过尝试之后并不能正确安装 protoc,一下记录能够顺利安装 protoc 与 protoc-gen-g ...

  6. ORA-08002: sequence TESTTABLE1_ID_SEQ.CURRVAL is not yet defined in this session (未完全解决)

    说明: 断开连接后 重新连接执行序列号当前值查找 会报错. 解决方法一:先查询序列号下一个值 SELECT testTable1_ID_SEQ.nextval from dual;

  7. <2014 05 21> 互联网时代的C语言——Go

    Go希望成为互联网时代的C语言. 多数系统级语言(包括Java和C#)的根本编程哲学来源于C++,将C++的面向对象进一步发扬光大.但是Go语言的设计者却有不同的看法,他们认为C++ 真的没啥好学的, ...

  8. IIS网站部署解决报错

    入坑2次,这次还是得马上总结起来== 部署网站报以上错 检查方法 步骤一:检查部署的网站路径是否正确 步骤二: 检查Internet信息管理器中,应用程序池的.net Framework版本,选择v4 ...

  9. python用whl文件安装包

    直接用pip安装包的时候有时会因为许多奇怪的原因安装失败,这时就需要祭出大杀器——whl文件 python3 -m pip install whl文件路径名 whl库:https://www.lfd. ...

  10. Numpy常用操作方法

    NumPy NumPy是高性能科学计算和数据分析的基础包.部分功能如下: ndarray, 具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组. 用于对整组数据进行快速运算的标准数学函数(无需编 ...