前不久用react和react-router写了个单页面应用,但写完后总感觉还欠缺点什么,组件间的状态和数据相对较为独立,而且兄弟组件间的通信很不方便。然后才了解到,在react应用中,可以存在一个负责整合数据流向的框架,于是就选择了redux.

根据我的理解下面说一下redux的思想:

redux由三个部分组成,即store,reducer以及action,直观一点,你可以把store理解为数据库,reducer是事件处理函数,action是触发事件。为什么可以这么理解呢,因为整个redux的大致逻辑是这样的:

1 dispatch(action),即触发action,(事件发生)

2 reducer根据当前所触发action执行相对应的函数,更新state,(执行事件处理函数,更新数据库数据)

3 store的state会为应用所获取,像数据库一样

当然可能并不是那么契合,但大致的可以这么理解。现在我们再仔细的看一看redux的数据流。

1 dispatch的action会被reducer捕获到,其实是action先被传送至store,再由store交付给reducer的,因为dispatch是store的方法,action通过回调到达的store,而之前我们在创建store的时候使用了这样的声明 var store = createStore(reducer),使得store与reducer建立了某种联系,自然的,reducer能够接收到触发的action。

2 上面是redux内部数据流的实现,但是redux与应用之间的数据流动是怎么建立起来的呢?因为一般来说,是由应用的视图触发action,然后redux的reducer根据接收到的action执行相应的处理函数更新store的state,而state又是作为数据来源与应用绑定的,所以store的state一更新,应用视图也会同步刷新。所以这里的问题是,应用是如何获得dispatch action的能力以及来自store的数据的呢?这个就需要借助react-redux的Provider以及connect组件了。

通过Provider组件为应用组件再加一层外壳,并传入整个应用的store。

 
connect组件负责链接store与应用。其中select函数会接收到来自store的state,在这里可以对state进行相应的预处理再返回应用所需state,state会连同store的dispatch方法以属性方式传入App组件即应用组件。
 
 

todo项目,说明整个项目的核心思想

redux的数据流思想大致如此,但这只是我自己的理解,可能会有所纰漏。

看了redux官方文档之后,照着葫芦画瓢也实现了一个todo小应用。


整个应用的编写思路其实不外乎上面所谈及的那些。

但是需要注意的是,上面截图中的第一条todo其实是通过异步添加上去的,然而dispatch只能触发同步的action,即传递普通的action对象,因为这样我们的action才能被reducer所接收到并触发相对应的处理函数。所以,如果需要触发异步的action的话,常规的方法是不行了的,我们需要使用点小技巧。这里又涉及到redux中间件(middleware)的概念了。简单介绍下,所谓中间件,就是在action被触发以及还没被reducer接收到之间这段时间所执行的一段函数,其内部封装有dispatch方法。中间件的存在是dispatch扩展的唯一标准方式。

我们想要使用中间件的话,需要借助applyMiddleware方法,它能够使中间件与store建立某种联系,使得store的dispatch和getState方法传入中间件。

说回我们之前所说的异步action,异步请求的实现我们可以借助于redux-thunk中间件,这个中间件会去拦截异步action,因为一般情况下异步action是action创建函数所返回的一个函数,所以redux-thunk中间件会替我们去执行这个函数。执行的最后,一般会dispatch普通的action对象,reducer捕获到此action对象,做出相应。

这是我们的异步action创建函数,会返回一个异步函数

//异步action
export function asyncAction(){
return function(dispatch, getState){
setTimeout(function(){
dispatch(addTodo("2秒钟过去啦!你还没添加新的任务,我来帮你添加一个吧!"))
},)
}
};

然后我们dispatch它

dispatch(asyncAction());

因为返回的是异步action对象(函数),会被redux-thunk拦截并执行,执行的最后dispatch一个普通的action事件,成功添加一条todo。

完整的代码在这里 https://github.com/JerelLin/redux-todo

睡觉

数据流 in redux的更多相关文章

  1. 实例讲解react+react-router+redux

    前言 总括: 本文采用react+redux+react-router+less+es6+webpack,以实现一个简易备忘录(todolist)为例尽可能全面的讲述使用react全家桶实现一个完整应 ...

  2. 6周学习计划,攻克JavaScript难关(React/Redux/ES6 etc.)

    作者:余博伦链接:https://zhuanlan.zhihu.com/p/23412169来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 和大家一样,最近我也看了Jo ...

  3. 深入理解Redux

    前面的话 Redux是Flux思想的另一种实现方式.Flux是和React同时面世的.React用来替代jQuery,Flux用来替换Backbone.js等MVC框架.在MVC的世界里,React相 ...

  4. redux 简介

    概述 Redux 本身是个极其简单的状态管理框架, 它的简单体现在概念少, 流程明确. 但是, 正是因为简单, 使用上没有强制的约束, 所以如果用不好, 反而会让状态管理更加混乱. 我觉得, 用好 R ...

  5. Redux学习笔记-基础知识

      Redux概述 是什么:Redux是管理状态的容器,提供可预测的状态管理. 怎么做:Redux主要是用来管理组件或者应用的状态,本质上跟一个事件处理器差不多.通过分发action触发reduce来 ...

  6. redux和mobx比较(二)

    Redux Redux 是 JavaScript 状态容器,提供可预测化的状态管理. 三大核心 在 Redux 中,最为核心的概念就是 action .reducer.store 以及 state,那 ...

  7. Redux使用

    思想 应用中所有的state都以一个对象树的形式储存在一个单一的store中.唯一能改变state的办法是触发action,一个描述发生什么的对象.为了描述action如何改变state树,需要编写r ...

  8. 状态管理之 Flux、Redux、Vuex、MobX(概念篇)

    本文是对 Flux.Redux.Vuex.MobX 几种常用状态管理模式的总结,偏向于概念层面,不涉及过多代码. 状态管理 什么是状态管理? 状态管理就是,把组件之间需要共享的状态抽取出来,遵循特定的 ...

  9. Redux 架构理解

    Redux 是一种前端“架构模式”,是 Flux 架构的一种变种,用来提供可预测的状态管理.虽然经常和 React 一起被提及,但是 Redux 却不仅仅只能用于 React,还可以将其运用到其他前端 ...

随机推荐

  1. Javascript的shift()和push(),unshift()和pop()方法简介

    栈方法: Javascript为数组专门提供了push()和pop()方法,以便实现类似栈的行为.来看下面的例子: var colors=new Array();       //创建一个数组 var ...

  2. C# 禁止修改已装箱了的值类型的字段值,但是可以通过接口的方式实现

    C# 默认是不能修改已装箱了的值类型中字段的值,但是可以通过 值类型实现指定的接口来改变 首先定义一个接口 interface IChange { void Change(int a, int b); ...

  3. FAT32文件系统

  4. lunece全文检索的入门与简单优化

    2016-12-15 项目中需要加载下面几个工具包 1 package com.cn.shupu.util; import java.io.BufferedReader; import java.io ...

  5. 农业银行快捷支付php版说明和实例代码

    接入的是shopnc,代码改改就可以用了,虽然不是一个完善的类,也可以按照类的方法直接调用,省得再去扣开发文档 农行在接收返回信息也会验证一次,还有一点就是页面通知返回结果 一定要用服务器通知,不然会 ...

  6. eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错? java.lang.ClassNotFoundException: com.branchitech.app.startup.AppStartupContextListener java.lang.ClassN

    eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错?java. ...

  7. python学习道路(day6note)(time &datetime,random,shutil,shelve,xml处理,configparser,hashlib,logging模块,re正则表达式)

    1.tiim模块,因为方法较多我就写在code里面了,后面有注释 #!/usr/bin/env python #_*_coding:utf-8_*_ print("time".ce ...

  8. Linux下解压命令大全 解压缩 tar bz2 zip tar.gz gz

    .tar解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)---------------.gz解压1:gunz ...

  9. js 时间函数封装

    html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  10. 如何给main传参数

    main 函数的参数有连个argc argcv[]  argc 是参数个数 argcv是参数的数组指针,且argcv的第一个参数是默认程序路径加程序名 给main传参数,需要在命令行启动程序时设置 如 ...