title: 关于Redux为核心的应用开发简介
date: 2017-04-20 08:05:04
categories: React-native
tags: Redux
问题出发点,当我们在UI组件中执行交互操作(点击,滑动,提交),我们要考虑到怎么来响应操作.函数式编程里有个图,有一个机器,从一边放入肉,另一边出火腿.这就是一个流程.application的操作其实就是解决
点击=>结果展示
的流程.
但是实际流程中需要解决的问题很多.我们要考虑怎么来更好的管理application 的状态问题. 具备javascript的基础知识,几个模式设计的东西,函数式编程的知识,React的知识,Redux的思想.可以说想在实际应用中玩转React/Redux/Redux-saga/immutable。需要掌握的东西还是很多的.
我先写一点具体的一些学习内容和需要的思想.
辅助观念转变的一个生活实例
先看个电灯电路
- 控制开关执行动作(操作),
- 电灯根据开关的动作来改变状态,
- 电灯的状态不是由自己决定的,电路里有电了就会亮,没电了就不亮,像木偶一样受到控制.
飞机座舱
各个仪表都和自己的传感器连接在一起,加上冗余备份的仪表,很难设计和维护
80-90年代的window操作系统(不止windows奥),起源其实就是早期美国国防部的科研项目.
传感器和显示屏就没有那么多线了.由数据总线来做集中统一处理.
理解React/Redux/Redux-saga架构的基础知识
函数式编程思想
函数式编程把流程拆为几个有联系的步骤,可以分解流程,易于维护.合起来完成一个具体的任务.
但是这只是函数式编程的一个组成部分
在javascript的函数式编程中用到很多概念
- 函数作为一类对象,可以作为数组的元素,可以作为函数的参数来传递.
- 基于流的编程(
redux-saga就是基于流的编程
).
-
闭包的概念
- high-order function 接受其他函数作为参数的函数
- 纯函数,对象的immutable,状态改变.
一个实际的流程分析
在用户提交表单的时候,我们想要做如下事情:
1.
校验一些输入信息 (简单, 写在组件里)
Validate方法,可以考虑导入redux-form组件,自带验证方法
2.
验证以后可以让提交按钮改为可以提交状态了
```
//login.UI.js登录组件
this.props.dispatch(userLoginRequest(submit_info));
//已经结束了,不要想太多,用户和组件的交互就是表单输入和提交按钮
//所以这里也执行这个过程就可以了.
```
3.
弹起提示信息(React组件化的优势,公共组件)
```
//login.Ui.js
//Lodaing组件
this.props.isFetching?<Loading>:null
```
4.
提交后端服务 (我们用fetch,这个是不变的,redux只是对流程的控制,并不是要改变实际做事的方法)
5.
拿到后端返回状态 (promise resolve)
6.
隐藏提示信息 (鸿门宴啊,摔杯为号,这不就是状态吗?)
```
//login.UI.js
this.props.isFetching?<Loading>:null
```
7.
更新redux store (reducer的操作)
//login.reducer.js
return state.merge(resolve.result);
8.
登录界面的任务完成了.根据业务需要跳转到对应的页面
//reducer.js
return state.merge(resolve.result);
//login.js
this.props.loginsuccess?(Action.Mycenter):(Action.refresh)
这里我们就把登录的流程做了分解.好处是很多的,流程都是根据状态来的变化的,
代码书写清晰,在每一步的dubug和测试过程都很容易,因为我们可以获取每一步的状态
由于有redux-logger的中间件存在,我们还可以查看每一步的状态变化.好像还有图形化的界面来显示state的变化.
总的原则是React组件只负责信息展示,简单的验证
复杂的逻辑现在全部在Redux中来实现
副作用(side effect)到底是个什么?
副作用其实就可以理解为由外部API提供的服务.这个服务和我们的app的流程是没有关系的,我们只需要给接口提供参数,等待接口返回数据就可以了.
React/Redux/Redux-saga
React的概念,原理
-
React内心是虚拟DOM,在react中的html代码实际是React渲染的模板
- React渲染动态内容的方式通过外部父组件传入的props和组件内部的state来实现
绝对不可以搞错的概念:组件之间要传递参数只能通过props来实现,state只能在组件内部使用,如果要把sate传递到其他组件,一定要经过转换
在React中,props和state都有两类不同的id来区分,不同的id类型是找不到对方的内容的.Redux的mapStateToProps方法就是把State的类型id转为props的类型id.
由此可以得出什么结论呢?
其实Redux也是一个React的组件.
******切记,切记*******
3.Connect这个函数是非常重要的函数
组件要订阅state的变化,能够订阅dispatch的方法都是通过connect函数来执行的.
Redux的出现
Redux负责把React的逻辑处理独立出来处理
Redux的要点有:
- 一个应用只有一个state
- state是只读的,这是immutable的概念.
- 修改state只能是用纯函数来执行,dispatch(Action(params))
一旦React的应用中加入Redux的构架以后,所有Appliction的核心就由组件转变到Redux中了.如果和传统的web的 browser/server来类比,Redux就变成了服务器的角色,state就承担了数据库的角色.
组件之前的state的改变现在要重新思考了.
组件之间就最好再也不要做数据的传递,组件要执行渲染的sate统一从Redux的store中获取
.
这一步思考方法的改变是极为重要的.
如果一个流程的过程非常的复杂,我们应该怎么来处理?
这一点其实有很多的解决办法,但是Redux-saga基本算是非常优秀的解决办法,严格贯彻了函数流式编程的思想,把一个复杂逻辑处理为一个数据流.
Redux-saga就是我们的救世主
redux-saga把我们上面的所有登录的流程可以写到一个工作流里面,香肠机器的组装
//login.saga.js
import {loginReuest loginFetching,loginSuccess,loginError } from '../actions/login';
//请求登录的数据流过程
export function* loginRequestFlow(submit_info) {
try {
yield put(loginFetching(isFetching:true))
const userInfoFromRemoteService = yield call(request,submit_info,'get');
yield put(loginSuccess(userInfoFromRemoteService));
const errorMessage = articleList.showapi_res_error;
if (errorMessage && errorMessage !== '') {
yield toastShort(errorMessage);
}
} catch (error) {
yield put(loginSuccess([]));
toastShort('网络发生错误,请重试');
}
}
export function* watchuserLoginRequest(sumbit_info) {
while (true) {
const {
sumbit_info
} = yield take(types.loginRequest);
yield fork(loginRequestFlow, );
}
}
//login.action.js
export function userLoginRequest(sumbit_info){
return {
types.loginRequest,
sumbit_info
}
}
Redux会监视这个数据流的触发
Redux saga 暴露了几个方法,称为 Effects,定义如下:
Fork
执行一个非阻塞操作。
Take
暂停并等待action到达。
Race
同步执行多个 effect,然后一旦有一个完成,取消其他 effect。
Call
调用一个函数,如果这个函数返回一个 promise ,那么它会阻塞 saga,直到promise成功被处理。
Put
触发一个Action。
Select
启动一个选择函数,从 state 中获取数据。
takeLatest
意味着我们将执行所有操作,然后返回最后一个(the latest one)调用的结果。如果我们触发了多个时间,它只关注最后一个(the latest one)返回的结果。
takeEvery
会返回所有已出发的调用的结果。
Redux-saga并没有改变Redux对于state的处理,只不过借用了es6/es7的方法对一个相关流程的changeState函数进行了包装而已.
所以理解Redux-saga的工作原理,对于React和Redux工作原理理解是前提.