Redux的工作流程
1.Redux 是一个专门用来管理数据业务或逻辑状态的框架,它也可以实现代码结构的规范化并提供组件之间通信的便利,而这两点,对于大型应用来说非常关键。
2.工作流程:

Redux 三大原则
单一数据源 整个应用的 state 被存储在一个 Object tree 中,且只存在于唯一的Store中。
state 是只读的 唯一改变 state 的方法就是触发 action,action 是一个用于描述发生事件的普通对象,视图部分只需要表达想要修改的意图,所有修改都会被集中化处理。
使用纯函数来执行修改 为了实现根据 action 修改 state值,我们就需要编写 Reducer。它是一个纯函数,接收先前的 state 和 action 返回新的 state ,随着应用的变大,你可以将它拆成多个小的 Reducer ,分别独立操作 state tree 中的不同部分。
2.具体工作步骤
Action
const add =()=>{
return {
type:"add",
data:id,
}
}
上边函数返回的就是一个 Action,它是一个包含 type 和 data 的对象。 Action 的作用就是告诉状态管理器需要做什么样的操作,正如上边的例子,就是要添加一条信息,这样就定义了一个Action,而 data 就是你做这个操作需要的数据。
Reducer
reducer 是一个函数(纯函数),接受 旧 state 和 action,根据不同的 Action 做出不同的操作并返回新的 state 。即:(state, action) => state
const reducer = (state,action)=>{
switch(action.type){
case "add":
state['newItemId'] = action.data;
return {...state};
case "delete":
delete state.newItemId;
return {...state};
default :
return state;
}
}
在没有任何操作的情况下,我们返回的 state 与原 state 相同。
Store
import { createStore } from 'redux';
const store = createStore(reducer);
这就是 store, 用来管理 state 的单一对象,其中有三个方法:
store.getState():获取state ,如上,经过 reducer 返回了一个新的 state,可以用该函数获取。store.dispatch(action):发出 action,用于触发 reducer 更新 state,store.subscribe(listener):监听变化,当 state 发生变化时,就可以在这个函数的回调中监听。
React-Redux
Redux 官方提供的 React 绑定库。
容器组件与傻瓜组件
在应用中,通常容器组件对于 Redux 可知,他们的子组件应该是"傻瓜的"(傻瓜组件),并且通过porps获取数据。 容器组件: 通过组件 state 属性维护自身及其子组件的数据,它可以向 Redux 发起 action ,从 Redux 获取 新state值。 傻瓜组件: 通过 props 调用回调函数,从 props 获取数据展示。
注入 Store
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provide } from 'react-redux';
import reducer from './reducer';
import App from './app';
const store = createStore(reducer);
class RootComp extends React.Component{
render(){
//...
return (//将整个视图结构包进 Provider
<Provider store={store}>
<App/>
</Provider>
)
}
}
ReactDOM.render(<RootComp/> ,document.getElementById('root'));
connect#
该方法用于从 UI 组件生成容器组件,
import React from 'react';
import { connect } from 'react-redux';
import Home from './home';
class AppContainer extends React.Component{
render(
return (
<Home/>
);
)
}
const App = connect()(AppContainer);//这里的App就是生成的容器组件。
export default App;
connect( mapStateToProps , mapDispatchToProps , mergeProps , options )();
连接 React 组件与 Redux Store
mapStateToProps该参数为一个function mapStateToProps (state,[ownProps]){...},定义该参数后组件就可以监听 Redux Store 的变化,任何时候只要store发生变化,该函数就会被调用,该函数必须返回一个纯对象,它会与组件的 props 结合,而第二个参数 ownProps 被指定时,它代表传递到该组件的props,且只要组件收到新的 props ,mapStateToProps 就被调用。mapDispatchToProps通常我们会将该参数省略,此时默认情况下,dispatch 会注入到组件的props中,在你需要出发 action 的地方(可能是某个事件函数)使用该disaptch 函数将 action 发出。
例子:


在上边例子中,我们只要点击下添加链接,组件就会通过点击事件触发 dispath 函数 发送 action 到 store 中的 reducer, reducer 则根据 action 的 type 来决定执行什么操作,之后在 store 中新增一条记录(newItemId)后返回一个新的 state (里边包含Store中发生改变后的所有值),由于组件使用 connect 将自己与 Store 绑定起来,Store 中的值发生变化就会执行 mapStateToProps,将新的 state 放入组件的 props,从而引发组件的渲染。
3. 异步中间件
也许你也已经发现了前边的介绍中有个关键的问题没解决,那就是异步操作(最典型的就是通过ajax访问后台数据)。Action 发出以后,Reducer 立即计算出 State,这叫同步,Action 发出之后,过段时间再执行 Reducer,这就是异步。 如和何才能让 Reducer 在异步操作结束后自动执行呢?这就需要异步中间件来解决。
中间件通过对 store.dispatch 进行改造,在发出 Action 和执行 Reducer 这两步之间添加其他功能。 中间件可以做很多事情,这里主要讲解异步中间件redux-promise-middleware的使用。
//Store.js 加载中间件
import { applyMiddleware,createStore } from 'redux';
import createPromiseMiddleware from 'redux-promise-middleware';
import reducer from './reducers/index';
const store = createStore({//createStore 可以接受应用初始状态作为参数,这时, `applyMiddleware` 就是第三个参数。
reduer,
applyMiddleware([createPromiseMiddleware()])
});
export default store;
发起异步action#
//actions.js
export const getTodos = () => {
const apiUrl = `/todos`;
return {
type: GET_TODO,
//属性 payload 值为 Promise 类型(中间件据此判断是否需要异步处理)
payload: fetch(apiUrl).then(response => {
if (!response.ok) {
//请求返回的可能是500等错误,也会执行到这里,需将状态设置为 rejected
return Promise.reject(response.status);
}
return response.json();
})
};
}
处理异步 actions#
一般 action 的处理,发起和处理是一一对应的,而异步 action 则有三个 action 来处理,分别对应异步的三种状态
${GET_TODO}_PENDING异步请求执行后会立刻 dispatch 此 action,表示请求已发出,正在等待返回值${GET_TODO}_FULFILLED异步请求成功后会 dispatch 此 action,注意 Response 只要回来,即使是 500,也会执行到这里${GET_TODO}_REJECTED异步请求失败后会 dispatch 此 action
上述三个 action 及后缀皆为中间件
redux-promise-middleware的约定,不同中间件约定可能不一致。
//reducer.js
case `${GET_TODO}_PENDING`: {
return {
status: FetchStatus.LOADING,
}
}
case `${GET_TODO}_FULFILLED`: {
return {status: FetchStatus.SUCCESS, items: action.payload};
}
case `${GET_TODO}_REJECTED`: {
return {status: FetchStatus.FAILURE, error: action.payload};
}
Redux的工作流程的更多相关文章
- 轻松理解Redux原理及工作流程
轻松理解Redux原理及工作流程 Redux由Dan Abramov在2015年创建的科技术语.是受2014年Facebook的Flux架构以及函数式编程语言Elm启发.很快,Redux因其简单易学体 ...
- Redux学习之我对于其工作流程的理解和实践
目录 1 工作流程图 2 各部位职责 3 Demo 1 工作流程图 2 各部位职责 我在理解这个流程图的时候,采用的是一种容易记住的办法,并且贴切实际工作职责. 我们可以把整个Redux工 ...
- struts2工作流程
struts2的框架结构图 工作流程 1.客户端请求一个HttpServletRequest的请求,如在浏览器中输入http://localhost: 8080/bookcode/Reg.action ...
- SecondaryNameNode的工作流程
SecondaryNameNode是用来合并fsimage和edits文件来更新NameNode和metadata的. 其工作流程为: 1.secondary通知namenode切换edits文件 2 ...
- Storm 中什么是-acker,acker工作流程介绍
概述 我们知道storm一个很重要的特性是它能够保证你发出的每条消息都会被完整处理, 完整处理的意思是指: 一个tuple被完全处理的意思是: 这个tuple以及由这个tuple所导致的所有的tupl ...
- gitlab工作流程简介
gitlab工作流程简介 新建项目流程 创建/导入项目 可以选择导入github.bitbucket项目,也可以新建空白项目,还可以从SVN导入项目 建议选择private等级 初始化项目 1.本地克 ...
- Git 工作流程
Git 作为一个源码管理系统,不可避免涉及到多人协作. 协作必须有一个规范的工作流程,让大家有效地合作,使得项目井井有条地发展下去.”工作流程”在英语里,叫做”workflow”或者”flow”,原意 ...
- Spark基本工作流程及YARN cluster模式原理(读书笔记)
Spark基本工作流程及YARN cluster模式原理 转载请注明出处:http://www.cnblogs.com/BYRans/ Spark基本工作流程 相关术语解释 Spark应用程序相关的几 ...
- tornado 学习笔记10 Web应用中模板(Template)的工作流程分析
第8,9节中,我们分析Tornado模板系统的语法.使用以及源代码中涉及到的相关类,而且对相关的源代码进行了分析.那么,在一个真正的Web应用程序中,模板到底是怎样使用?怎样被渲染? ...
随机推荐
- 如何运行一个Vue项目
一开始很多刚入手vue.js的人,会扒GitHub上的开源项目,但是发现不知如何运行GitHub上的开源项目,很尴尬.通过查阅网上教程,成功搭建好项目环境,同时对前段工程化有了朦朦胧胧的认知,因此将环 ...
- python实现单线程多任务非阻塞TCP服务端
代码 # coding:utf- from socket import * # .创建服务器socket sock = socket(AF_INET, SOCK_STREAM) # .绑定主机和端口 ...
- Petrozavodsk Winter Camp, Day 8, 2014, Fine Brochures
1的个数-块的个数+多减的个数+flag 多减的只会在一个循环末尾出现 #include <bits/stdc++.h> using namespace std; #define rep( ...
- MySQL数据库(1)
你好,我是Sundy左左,一名初级数据分析师,我在建设一个属于初学者笔记的乐园,在这里我将自己学习的东西分享出来,也许对你有用也许对你没用,但都欢迎您指出我的错误和改进的地方.我是一个初级的数据分析师 ...
- ThinkPHP5.0源码学习之缓存Cache(一)
一.文件 1.缓存配置文件:thinkphp\convention.php 2.缓存文件:thinkphp\library\think\Cache.php 3.驱动目录:thinkphp\librar ...
- jsp的page、request、session、application四个作用域的作用
1.page作用域也是最小的作用域,它只能在当前页面中使用. 2.request作用域主要是发送请求,但只能在两个页面之间发送一次请求. 3.session作用域是一个会话,也就是一个浏览器,意思是说 ...
- mysql 插件相关命令
# 查看mysql的插件 show plugins \G # 安装mysql 插件 INSTALL PLUGIN spartan SONAME 'ha_spartan.so'; # 卸载 UNINST ...
- spark优化整理
- SQL Server2008R2循环语句
单循环语句 declare @i nvarchar(36) declare @LOCNUM nvarchar(36),@OBJECTTYPE nvarchar(36),@LOCDESC nvarcha ...
- js 中innerHTML,innerText,outerHTML,outerText的区别
开头说下innerText和outerText只在chrome浏览器中有效 定义和用法 innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML,包括标签. 来看代码 <!DOC ...

