在react-native中使用redux
redux是什么?
redux
是一个用于管理js应用状态的容器。redux
出现时间并不是很长,在它出现之前也有类似功能的模块出现,诸如flux
等等。redux
设计的理念很简单,似乎最初这个开发团队就有让redux
可以方便融入在server, browser, mobile client端的打算。目前在github上redux-*
的第三方中间件、插件越来越多。如果react项目中想使用redux
,那么就有react-redux
插件来完成配合。而作为开发者,可以使用这些优秀的第三方资源来开发/优化已有的项目,也是一件很欢乐的事。
设计的动机
在redux.js.org里有关于编写redux的动机描述(our code must manage more state than ever before
),在现实的生活中,单页应用越来越多,而且需要维护的状态也越来越复杂,诸如维护数据更新、UI更新、本地数据存储等这些都是我们在js应用常常需要处理的情景,当然这里多数都会涉及到异步处理。而redux
本身就是为了解决这些问题,而是将所有的变化进行统一流程处理,会使我们的程序状态变化清晰可见。redux最终目的就是让状态(state)变化变得可预测。
使用的三原则
- 1, Single source of truth
单一数据源。整个应用的state,存储在唯一一个object中,同时也只有一个store用于存储这个object. - 2, State is read-only
状态是只读的。唯一能改变state的方法,就是触发action操作。action是用来描述正在发生的事件的一个对象。 - ** 3, Changes are made with pure functions**
在改变state tree时,用到action,同时也需要编写对应的reducers才能完成state改变操作。
在上面的三原则中,我们看到了store
, action
, reducer
这些词,那就先说说redux
是怎么进行应用状态(state)维护管理的呢。
redux状态管理的流程
- action是用户触发或程序触发的一个普通对象。
- reducer是根据action操作来做出不同的数据响应,返回一个新的state。
store的最终值就是由reducer的值来确定的。(一个store是一个对象, reducer会改变store中的某些值)
redux流程.png
上图简单画了下redux状态改变的流程。action
-> reducer
-> 新store
-> 反馈到UI上有所改变
。
下面再给个具体实例:
store用于维护状态的容器,包括了应用的多个状态,比如说用户是否登录、用户信息、用户任务等等。action是一个普通对象,用于指明是哪种操作,这样才能在reducers中进行识别。而众多reducer是负责返回新的state的函数。在实际应用中,你需要将store或store的某个值绑定到界面,这样更新store的时候,该页面可以监听到值的更新,然后进行一些页面更新操作/跳转操作等。
redux在实际使用中需要用到的高级部分
redux设计如此简洁,以至于并没有进行异步处理的功能。但是留下了middleware这个概念。可以自己编写符合需要的中间件。目前第三方的中间件基本可以完成一个复杂应用的架构设计。那就先说一说,怎么去处理异步请求呢。
首先推荐redux-thunk
,可以看到它的源码很简洁。就是判断action是否是函数,如果是函数进行递归式的操作。所以在redux
中的异步,只能出现在action中,而且还需要有中间件的支持。
export default function thunkMiddleware({ dispatch, getState }) {
return next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
return next(action);
};
}
// redux-thunk的源码
同步action与异步action最大的区别是:
同步只返回一个普通action对象。而异步操作中途会返回一个promise函数。当然在promise函数处理完毕后也会返回一个普通action对象。thunk
中间件就是判断如果返回的是函数,则不传导给reducer,直到检测到是普通action对象,才交由reducer处理。
实例说说redux的使用。
实例代码在github上查看地址。该实例只演示了登录过程,是比较基础的redux使用案例。
项目相关代码均在js
目录下。目录中可以看到actions
, reducers
, store
等子目录。
实例action
actions/user.js
目录中定义了用户登录操作的action creator
:
- 第22行的
logIn
logIn
是一个异步action,注意函数内部的写法与redux-thunk
的定义要相同。 - 第38行的
skipLogin
- 第47行
logOut
这些creator,产生的action状态有LOGGED_DOING
,LOGGED_IN
,LOGGED_ERROR
,LOGGED_OUT
四种状态。
第8行变量testUser
, 第15行变量skipUser
分别是模拟针对普通登录成功后(这里用的是fetch www.baidu.com,真实情况下需换成真实的登录接口)的用户对象,跳过登录后默认的用户对象。
接下来再看看reducers
怎么去处理这些action?
实例reducer
reducers/user.js
中:
- 第5行的
initialState
定义了最开始的应用状态(即用户未登录的情况下的state)。 - 第13行,对每个传过来的
action
进行switch
,每个action都需要返回一个state对象,如果不需要变动,则返回原对象(switch中的default返回值)。需要变动,则返回一个新的state, 可以看到当type为LOGGED_DOING
,LOGGED_IN
,LOGGED_OUT
时,返回的对象跟原始对象都会有一些字段的差别。
reducers/index.js
中:
- 第5行
combineReducers
是将应用的state进行组合。 - 目前demo中只有用户信息,所以只看到第6行
userStore
这一个key,在一个业务复杂的应用里,需要保存很多应用和用户交互产生的信息(比如说用户聊天列表等信息)。
实例store
再来看看store
的处理:
store/index.js
中定义了store的行为(包括中间件):
- 第23行的
applyMiddleware
会将中间件应用在redux action过程中。 - 第10行自定义一个
logger
中间件,该中间件的目的是打印出当前的触发的action
以及出发后的state
变化。 - 第27行,33行 使用了
redux-persist
这个第三方插件来将store对象存储到本地,以及从本地恢复数据到store中,比如说保存登录信息,下次打开应用可以直接跳过登录界面。
程序入口
上面是定义。下面再来看如何在程序中使用:
在入口文件index.js
中:
- 第27行,需要将
store
作为属性传递给Provider
组件中。 - 第28行,可以看到的是真正渲染出的东西是
<Root/>
标签返回的东西。
那就来看看root.js
里的内容。
root.js
中:
- 第48行的
render
主要实现了Navigator
导航器的处理,并用自定义的一个Router
(第27行)进行封装了下。 - 第59行,在末尾的
select
函数,是将store
中的某些值复制到当前组件的props中,注意这里需要用connect
函数进行绑定,否则store
变化,不会反馈到Root
组件中。isLoggedIn
这个变量便被复制到当前的Root组件中,在Root内部方法中可以访问。 - 第16行,
constructor
里,会对登录状态进行判断,如果检测到已经登录了,则会修改Navigator
初始的路由设置(第10行设置的),使应用直接显示MainPage
。
登录页面。
那再看看登录页面pages/login.js
中的用户操作:
上面的3个图片是整个pages/login.js
的源码。
- 第160行,指定了该组件会与
store
的哪些值进行连接。分别是isLoggedIn
,user
,status
。 - 第129行,定义了
Text
的onPress
操作。handleLogin
是绑定的操作方法,方法内容见第60行。在71行时,会触发logIn
这个action。 - 触发
logIn
后,会先进入LOGGED_DOING
状态,此时说明在登录中。在第42行,有对该状态进行监听,如果为该状态,会将弹窗弹出,提醒为loading态。 - 第33行,在
shouldComponentUpdate
中,对即将变化的nextProps进行与目前的props进行对比。比如说logIn
执行登录完成后,第35行检测到isLoggedIn
为true,则执行toMain
函数(即跳转到主页中)。
看下最终的demo交互效果。
作者:巨巨
链接:https://www.jianshu.com/p/2c43860b0532
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
引用原文:https://www.jianshu.com/p/2c43860b0532
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!
在react-native中使用redux的更多相关文章
- 在 React Native 中使用 Redux 架构
前言 Redux 架构是 Flux 架构的一个变形,相对于 Flux,Redux 的复杂性相对较低,而且最为巧妙的是 React 应用可以看成由一个根组件连接着许多大大小小的组件的应用,Redux 也 ...
- react native 中的redux 理解
redux 中主要分为三大块,分别是Action Reducer 与Store. 1.Action是js的一个普通对象,是store数据的唯一来源.通过store.dispath()讲action传到 ...
- React Native 中使用Redux
参考https://jspang.com/detailed?id=48和印度同事的代码简单整理一下在RN中使用Redux的步骤 1. 首先我们应该先了解Redux是什么,什么情况下需要用到它 在Red ...
- react native 中的redux
一.使用redux 的条件: 1.某个组件的状态,需要共享: 2.某个状态需要在任何地方都可以拿到: 3.一个组件需要改变全局状态: 4.一个组件需要改变另一个组件的状态. redux 说明白点, ...
- React Native 中 CSS 的使用
首先声明,此文原作者为黎 跃春 React Native中CSS 内联样式 对象样式 使用Stylesheet.Create 样式拼接 导出样式对象 下面的代码是index.ios.js中的代码: / ...
- react native中的欢迎页(解决首加载白屏)
参照网页: http://blog.csdn.net/fengyuzhengfan/article/details/52712829 首先是在原生中写一些方法,然后通过react native中js去 ...
- React Native中的网络请求fetch和简单封装
React Native中的网络请求fetch使用方法最为简单,但却可以实现大多数的网络请求,需要了解更多的可以访问: https://segmentfault.com/a/1190000003810 ...
- [转] 「指尖上的魔法」 - 谈谈 React Native 中的手势
http://gold.xitu.io/entry/55fa202960b28497519db23f React-Native是一款由Facebook开发并开源的框架,主要卖点是使用JavaScrip ...
- [转] 在React Native中使用ART
http://bbs.reactnative.cn/topic/306/%E5%9C%A8react-native%E4%B8%AD%E4%BD%BF%E7%94%A8art 前半个月捣腾了一下Rea ...
- 如何在非 React 项目中使用 Redux
本文作者:胡子大哈 原文链接:https://scriptoj.com/topic/178/如何在非-react-项目中使用-redux 转载请注明出处,保留原文链接和作者信息. 目录 1.前言 2. ...
随机推荐
- node读写Excel操作
目支持写Excel的node.js模块: node-xlsx: 基于Node.js解析excel文件数据及生成excel文件: excel-parser: 基于Node.js解析excel文件数据,支 ...
- python 之 多进程
阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiprocessingpython中的多线程 ...
- c++ new(不断跟新)
1.基础知识 /* 可以定义大小是0的数组,但不能引用,因为没有指向任何对象 new string[10]调用类的默认构造函数 new int[10]没有初始化,但new int[10]()会将数组初 ...
- git base commond
打开Git Bash 命令:先写 git status, 它会告诉你怎么做 1. git pull (把git库中代码拉下来) 2. $ git status (查看状态) 3. $ gi ...
- 170223、Tomcat部署时war和war exploded区别以及平时踩得坑
war和war exploded的区别 在使用IDEA开发项目的时候,部署Tomcat的时候通常会出现下边的情况: 是选择war还是war exploded 这里首先看一下他们两个的区别: war模式 ...
- 12.php中无比坑爹的构造函数。
当你在php类中,写一个构造方法时,记得,一定要用__这是两个下划线,而不是一个.......... <?php class Car { // function _construct() { / ...
- 如何cancel掉慢查询
百度Elasticsearch-产品描述-介绍-百度云 https://cloud.baidu.com/doc/BES/FAQ.html#.E5.A6.82.E4.BD.95cancel.E6.8E. ...
- HTTP 常见状态码
1. 以"1"开头(临时响应) 100: Continue,请求者应当继续提出请求;表示服务端已经收到请求的一部分,正在等待其余部分; 101: Switching Protoco ...
- js浏览器调试
JS调试 sources界面(主要用来控制执行) 打断点,右上角四个按钮分别是:跳到下一个断点,单步调试,跳入,跳出. 鼠标悬浮在变量上可以查看变量的属性: console界面(主要用于查看输出) 主 ...
- 汉澳sinox2014没有黑屏,一个能够依靠的安全避风港
首先汉澳sinox2014没有验证server,根本就没办法区分正版和盗版 其次汉澳sinox2014安装也没有系列号cdkey等东西,直接安装无干扰 最后汉澳sinox2014不会有黑屏这样的东西. ...