思考题:

react+redux开发这么一个原型,要怎么开发?

整个redux流程的逻辑非常清晰,数据流是单向循环的,就像一个生产的流水线:

store(存放状态) -> Container(显示状态) -> reducer (处理动作)-> store

redux画图理解:

redux 只是定义了应用的数据流程,只解决了 “数据层”(model layer) 的问题,

一般还会使用 react, angular 等作为“显示层” (UI layer) 来一起使用,我们项目采用 react 作为显示框架。

分工明确:

工作分配:
1. 应用的基础配置工作应由前端开发主管负责,大家不必详细理解。
2. 布局组
container、component
静态布局 HTML + CSS
动态布局 使用 JSX 语法对静态布局做动态渲染处理
3. 逻辑组
action开发 - 制作redux流程的action
reducer开发 - 制作redux流程的reducer

- src 源码文件夹:包含项目源码,我们基本都在这个文件夹下做开发

    - containers   容器文件夹:存放容器组件,比如 “苹果篮子”
    - components   组件文件夹:存放普通显示组件,比如 “苹果”
    - actions      actions文件夹:存放可以发出的action
    - reducers     reducers文件夹:存放action的处理器reducers
    - services     服务文件夹:存放经过封装的服务,如 ajax服务, 模拟数据服务
    - styles       样式文件夹:存放应用的样式,如css, scss
    - images       图片文件夹:存放图片资源
    - apis         开发接口文件夹:存放开发接口文档

action创建函数(action creator),返回纯对象(纯粹的对象)

reducer就是一个纯函数,保持reducer的纯净很重要,不要在reducer里请求API和路由跳转
不要调用非纯函数,如 Date.now() 或 Math.random()。单纯执行计算。

在reducer里应该设计好state结构,有时候会根据后台返回的json数据设计

动态渲染:
根据一个state数据对象来显示内容
1. 确定state数据结构 (leader约定好数据结构,并在reducer中给出)
2. 知道容器的state是store中state的一部分
3. 自己定义普通的state,并在文件中说明清楚

动态布局:
HTML+CSS基础和JSX 语法能力


state的格式我们会在其对应的reducer中规定(因为我们需要在reducer中提供对应state的默认值)

Store(存储state)
store.getState()获取state
store.dispatch(action)更新state
store.subscribe(listener)注册监听器
unsubscribe = store.subscribe(listener)执行返回的函数unsubscribe()注销监听器

再次强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。

1. 狭义的 action

狭义的action是指一个简单的对象,对象的结构如下,只要在对象内包含type属性指明action的名称即可,同时,在对象的其他属性里,可以以任何形式自由保存其他相关数据。

let action = {
    type: 'ACTION_NAME',
    ...
}

一般 type 的内容使用 大写字母+下划线 的格式。

在这个定义的基础上,业界提出以一种标准 action, 叫做 Flux Standard Action , 该标准下的action除了type属性之外,只允许多加(不是必须包含)这三个属性:payload,error,meta。

let FSA = {
    type: 'ACTION_NAME',
    payload: <bool | number | string | object>, //action的负载,可以是数据或 error 对象
    error: <bool>, // 指明该action是否是一个以 error 为负载的action
    meta: <string> // action元数据, 包含解释该action含义的信息
}

我们宅印约定都要使用 Flux Standard Action,下面是吃苹果 action:

let FSA = {
    type: 'EAT_APPLE',
    payload: 3, // 负载是3, 说明吃掉3号苹果, 这里也可以写成 { id : 3 }
    meta: 'This action will eat an apple!' // (不是必须的)
}

一个action只是一个对象,他需要根据时机被 store 的 dispatch 函数调用才会开始进行处理:store.dispatch(action_1)。

2. 广义的 action

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

thunk 其实就是一个代码片段,可以简单理解为一种特定的函数,我们可以dispatch 这个thunk。 thunk函数具有如下的签名

(dispatch, getState) => {
    //在函数体内可以使用 dispatch 方法来发射其他 action
    //在函数体内可以使用 getState 方法来获取当前的state
}

下面是一个我们摘苹果动作的例子:

let pickAppleAction = (dispatch, getState) => {
    ajax({
        url: '/pickApple',
        method: 'GET',
    }).done(data => {
        //发射普通 action
        dispatch({
            type: 'DONE_PICK_APPLE',
            payload: data.weight // 或者 payload: {weight: data.weight}
        });
    }).fail(xhr => {
        //发射普通 action, 其负载是一个error
        dispatch({
            type: 'FAIL_PICK_APPLE',
            payload: new Error(xhr.responseText) ,
            error: true
        });
    })
}
        

定义好之后,我们可以直接这样调用这个thunk:

dispatch( pickAppleAction )
接下来,我们来做进一步优化,把action统一为actionCreator , 我们不难察觉,每次都要书写{ type: 'ACTION_NAME' ... } 是很麻烦也很容易出错的,

actionCreator 就是为解决这个问题而生的,actionCreator 就是一个产生特定action(这里指广义的action)的函数,下面来看简单的actionCreator 例子:

//传统写法
var eatApple = function(id) {
  return {
    type: 'EAT_APPLE', 
    payload: id
  }
}

// es6 写法
let eatApple = id => ({
  type: 'EAT_APPLE', 
  payload: id
})
这样一来,一方面是使用起来比较简单方便,另一方面是具有文档作用。
只需要这样发射action就可以啦:

dispatch(eatApple(3))
普通action的actionCreator封装工作, 可以使用 redux-actions 自动完成, 查看其文档就可以快速上手,可以根据情况使用。

组件的包装

任何一个从 connect() 包装好的组件都可以得到一个 dispatch 方法作为组件的 props,以及得到全局 state 中所需的任何内容。

connect() 的唯一参数是 selector。此方法可以从 Redux store 接收到全局的 state,然后返回组件中需要的 props。最简单的情况下,可以返回一个初始的 state (例如,返回认证方法),但最好先将其进行转化。

异步action

最后,如何把之前定义的同步 action creator 和 网络请求结合起来呢?标准的做法是使用 Redux Thunk middleware。

要引入 redux-thunk 这个专门的库才能使用。我们后面会介绍 middleware 大体上是如何工作的;

目前,你只需要知道一个要点:通过使用指定的 middleware,action creator 除了返回 action 对象外还可以返回函数。这时,这个 action creator 就成为了 thunk。

当 action creator 返回函数时,这个函数会被 Redux Thunk middleware 执行。

这个函数并不需要保持纯净;它还可以带有副作用,包括执行异步 API 请求。

这个函数还可以 dispatch action,就像 dispatch 前面定义的同步 action 一样。

我们仍可以在 actions.js 里定义这些特殊的 thunk action creator。



数据流程redux学习(一)的更多相关文章

  1. redux请求数据流程

    redux请求数据流程 store里面的index.js文件 import {createStore,combineReducers,applyMiddleware} from "redux ...

  2. redux学习

    redux学习: 1.应用只有一个store,用于保存整个应用的所有的状态数据信息,即state,一个state对应一个页面的所需信息 注意:他只负责保存state,接收action, 从store. ...

  3. React+Redux学习笔记:React+Redux简易开发步骤

    前言 React+Redux 分为两部分: UI组件:即React组件,也叫用户自定义UI组件,用于渲染DOM 容器组件:即Redux逻辑,处理数据和业务逻辑,支持所有Redux API,参考之前的文 ...

  4. redux学习总结

    redux学习总结 *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !imp ...

  5. HDFS读写数据流程

    HDFS的组成 1.NameNode:存储文件的元数据,如文件名,文件目录结构,文件属性(创建时间,文件权限,文件大小) 以及每个文件的块列表和块所在的DataNode等.类似于一本书的目录功能. 2 ...

  6. Redux学习及应用

    Redux学习及应用 一:Redux的来源? Redux 是 JavaScript 状态容器,提供可预测化的状态管理.Redux是由 Flux 演变而来,但受 Elm 的启发,避开了 Flux 的复杂 ...

  7. P2P小贷网站业务数据流程分享

    P2P小贷网站业务数据流程分享 引言 这是去年年底开发的一个项目,完成后和用户的衔接没有很好的做起来,所以项目就搁浅了.9月以来,看各路P2P风声水起,很是热闹:这里分享下我的设计文档,算是抛砖引玉, ...

  8. android Camera 数据流程分析

    这篇文章主要针对其数据流程进行分析.Camera一般用于图像浏览.拍照和视频录制.这里先对图像浏览和拍照的数据流进行分析,后面再对视频电话部分进行分析. 1.针对HAL层对摄像头数据处理补充一下 Li ...

  9. MapReduce的数据流程、执行流程

    MapReduce的数据流程: 预先加载本地的输入文件 经过MAP处理产生中间结果 经过shuffle程序将相同key的中间结果分发到同一节点上处理 Recude处理产生结果输出 将结果输出保存在hd ...

随机推荐

  1. hearbeart

    Heartbeat(Linux-HA工程的一个组件) Heartbeat 项目是 Linux-HA 工程的一个组成部分,它实现了一个高可用集群系统.心跳服务和集群通信是高可用集群的两个关键组件,在 H ...

  2. IT人常用的网站

    一.网页设计类 蓝色理想 http://www.blueidea.com 网页设计师联盟 http://www.68design.net 网页设计大本营 http://www.code-123.com ...

  3. Hibernate---基础配置

    hibernate.cfg.xml里可以设置一个值显示更详细的sql语句: <property name="format_sql">true</property& ...

  4. 关于CH340在STM32实现一键下载电路的研究(转)

    源:关于CH340在STM32实现一键下载电路的研究 在做基于STM32的多功能MP3播放器的课题时,在程序下载这部分时借鉴了正点原子开发板上的一键下载电路,采用CH340G这款芯片设计. 在画PCB ...

  5. PHP访问接口获取数据

    如:http://localhost/operate.php?act=get_user_list&type=json 在这里operate.php相当于一个接口,其中get_user_list ...

  6. 为什么无线信号(RSSI)是负值(转)

    源:为什么无线信号(RSSI)是负值 为什么无线信号(RSSI)是负值 答:其实归根到底为什么接收的无线信号是负值,这样子是不是容易理解多了.因为无线信号多为mW级别,所以对它进行了极化,转化为dBm ...

  7. angular中的$http配置和参数

    依赖:$httpBackend $cacheFactory $rootScope $q $injector 使用:$http(config); 参数: method:字符串,请求方法. url:字符串 ...

  8. iOS纯代码制作欢迎界面——UIScrollView, UIPageControl, UIImageView,UIButton, NSTimer

    欢迎界面,还是比较简单的,一个UIScrollView控件,一个UIPageControl,几个UIImageView即可摆平.在这里光玩这些,就显得诚意不足了.特意拓展一下,再加几个UIButton ...

  9. JNI错误总结(转)

    源:JNI错误总结 最近公司里要用JNI技术,用java去调用已经写好的本地DLL库.之前自己也没接触过相关技术,其中花了大部分时间在调试改错上面,网上对于错误的解决方案也不多,现在项目接近完工,自己 ...

  10. JNI 中文字符串传递(转)

    源:JNI 中文字符串传递 因为项目编码中通过JNI传递中文字符时出现乱码问题,特搜集了相关资料,整理如下: java内部是使用16bit的unicode编码(UTF-16)来表示字符串的,无论中文英 ...