博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redux 源码详解
阅读量:6718 次
发布时间:2019-06-25

本文共 3702 字,大约阅读时间需要 12 分钟。

redux 单向数据流的由来

  1. Flux将应用分成四个部分;
  • view 视图层;
  • Action 视图层发出的消息;(改变store里面的数据)
  • Dispatch(派发器)
  • Store (数据层) : 用来存在应用的状态(数据),一旦发生变动,就要提醒view更新页面。

redux单向数据流:

具体详情请见

Action

  • 定义. Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。

  • 狭义的Action

let action = {    type: 'ACTION_NAME',    ...}复制代码

注意: 一般 type 的内容使用 大写字母+下划线 的格式.

  • 广义的Action

    广义的 action 是指在中间件的支持下,dispatch 函数可以调用的数据类型,除了普通action之外,常见的有 thunk, promise 等。我们用常用的 thunk来举个例子

    什么叫thunk函数? 具体背景见阮一峰es6标准入门一书第17章Thunk函数的含义.在javaScript中函数将多参数函数替换成单参数的版本,且只接受回调函数作为参数。 例如:

var Thunk = function(fn){    return function(){        var args = Array.prototype.slice.call(arguments);        return function(callback){            args.push(callback);            return fn.apply.(this,args);        }    }}var readFileThunk = Thunk(fs.readFile);readFileThunk(fileA)(callback);复制代码
Thunk函数版本的action:复制代码
(dispatch, getState) => {     //在函数体内可以使用 dispatch 方法来发射其他 action    //在函数体内可以使用 getState 方法来获取当前的state}复制代码

ceateStore

通过该API创建一个store对象,该对象包含四个方法;

  1. getState();获取store中当前的状态。
  2. dispatch(action): 分发一个action,并返回这个action,这是唯一能改变store中数据的方式。
  3. subscribe(listener): 注册一个监听者,它在store发生变化时被调用。
  4. replaceReducer(nextReducer): 更新当前store里的reducer, 一般只会在开发模式中调用该方法。

redux middleware

  • Redux 是一个简单的同步数据流,当分发一个action时,reducer收到action后,更新state并通知view重新渲染。 当action发出后如果想要执行一些别的操作,该怎样处理,也就是说action发出后没有立即执行reducer,将redux变成异步. 这时就要借助中间件。

  • redux-middleware的数据流动.

  • 中间件的由来以及原理. 中间件的思想来源于koa. 核心思想:将middleware(函数)进行组合,将当前的middleware执行一遍作为参数传给下一个middleware去执行。

原理:

app.use((ctx, next) => {  ctx.name = 'Lucy'  next()})app.use((ctx, next) => {  ctx.age = 12  next()})app.use((ctx, next) => {  console.log(`${ctx.name} is ${ctx.age} years old.`) // => Lucy is 12 years old.  next()})// ... 任意调用 use 插入中间件app.go({}) // => 启动执行,最后会调用 callback 打印 => { name: 'Lucy', age: 12  }复制代码

ctx 参数就是 app.go 接受的对象。调用 app.go 其实会调用目标函数 app.callback,但是调用 app.callback 之前我们可以先让参数 ctx 通过一系列的中间件,最后才会传递给 app.callback。

使用 app.use 插入任意中间件,中间件是一个函数,可以被传入一个 ctx 和 next;调用 next 的时候会执行下一个中间件。如果不调用 next 会阻止接下来所有的中间件的执行,也不会执行 app.callback。

这里的app.use()就是一个实现中间件。

const app = {    middleware:[],    callback(){        console.log(ctx);    },    use(fn){        this.middleware.push(fn);    },    go(){        const reducer = (next,fn,i)=> {            fn(ctx,next)        }        this.middleware.reduceRight(reducer,this.callback.bind(this,ctx))();    }}复制代码
  • redux的applyMiddleware的源码.
function applyMiddle(){        (next) => (reducer, initialState) => {            let store = next(reducer,initialState);            let dispatch = store.dispatch;            let chain = [];            let middlewarAPI = {                getState:Store.getState,                dispatch: (action) => { dispatch(action)}            }            chain = middlewares.map(middleware => middleware(middlewarAPI));            dispatch = compose(...chain)(store.dispatch);            return {                ...store,                dispatch            }        }    }复制代码

一般这样应用middleware

const finalCreateStore = compose(    applyMiddleware(...middleware)    //DevTools.instrument())(createStore);const store = finalCreateStore(reducer);复制代码

middleware的一般写法

const m1 = store => next => action => {    let result = next(action);    switch (action.type) {        case APP_INCREMENT_LOADING:            globalProgressBar.incrementLoading();            break;        case APP_DECREMENT_LOADING:            globalProgressBar.decrementLoading();            break;    }    return result;};export default m1;复制代码

注:这里的compose函数请参考app.go或者参考上章FP一节; applyMiddle其实用了2个中间件的思想; 源码的详细解释:

作者个人博客: http://zhengchengwen.com 欢迎交流

转载于:https://juejin.im/post/5b17fd74f265da6e1d6ca9a5

你可能感兴趣的文章
《软件建模与设计: UML、用例、模式和软件体系结构》一一1.8 软件建模和设计方法的发展...
查看>>
web 应用通用数据访问层 Fetchr
查看>>
《vSphere性能设计:性能密集场景下CPU、内存、存储及网络的最佳设计实践》一1.2 建立基准...
查看>>
绕过 Windows 10 Cloud 限制 成功运行 Win32 应用程序
查看>>
Alamofire —— Swift 的 HTTP 客户端开发包
查看>>
《程序员的呐喊》一一1.13 弱类型机制够不够强
查看>>
Windows 10 Redstone 终将引入交互式动态瓷贴
查看>>
《机器人与数字人:基于MATLAB的建模与控制》——3.1节平移和旋转
查看>>
《途客圈创业记:不疯魔,不成活》一一1.3 iWeekend创业周末
查看>>
《精通SNMP》——2.4 标签类型和子类型
查看>>
《云数据中心构建实战:核心技术、运维管理、安全与高可用》——导读
查看>>
《Python自动化运维:技术与最佳实践》一2.4 探测Web服务质量方法
查看>>
《Android UI基础教程》——2.4节显示列表
查看>>
《Scala机器学习》一一1.5 使用Scala和Spark的Notebook工作
查看>>
Fast-FrameWork v0.1.1,JDK 8 MVC 框架
查看>>
《IP组播(第1卷)》一导读
查看>>
《高效能程序员的修炼》一学会读源代码
查看>>
3大军团、266个项目,菜鸟技术如何玩转双11项目管理?
查看>>
魅族隔空回应雷军:开放 Flyme 对抗 MIUI
查看>>
成为阿里云大使的笔记
查看>>