Redux概览
简介
- Redux 是一个有用的架构
- Redux 的适用场景:多交互、多数据源
工作流程图

action
用户请求
//发出一个action
import { createStore } from 'redux';
const store = createStore(fn);
//其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置
const action = {
type: 'ADD_TODO',
data: 'Learn Redux'
};
store.dispatch(action);
Reducer
状态机
Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。
Reducer 是纯函数,就可以保证同样的State,必定得到同样的 View。但也正因为这一点,Reducer 函数里面不能改变 State,必须返回一个全新的对象
const defaultState = 0;
const reducer = (state = defaultState, action) => {
switch (action.type) {
case 'ADD':
return {
...state,
data: action.data
}
default:
return state;
}
};
Recucer的拆分
//index
import {combineReducers} from 'redux';
import proIndex from './proIndex';
import product from './product'
export default combineReducers({
proIndex,
product,
});
//product
import actions from '../action/index'
import {getDocMenu} from "../action/user/product";
const {
GET_PRODUCT_DOCUMENT_SUCCESS
} = actions;
export default (state = {},action) =>{
switch (action.type) {
case GET_PRODUCT_DOCUMENT_SUCCESS:
return{
...state,
getDocMenu: action.data,
}
default:
return state;
}
}
//proIndex
import actions from '../action/index';
const {
GET_SERVICE_CLASSIFICATION_SUCCESS,
GET_SERVICE_SUBJECT_SUCCESS,
} = actions;
export default (state = {},action) => {
switch (action.type) {
case GET_SERVICE_CLASSIFICATION_SUCCESS:
return {
...state,
getServiceClass: action.data,
};
case GET_SERVICE_SUBJECT_SUCCESS:
return {
...state,
getServiceSubject: action.data,
};
default:
return state;
}
};
store
数据仓库
import { createStore } from 'redux'
import todoApp from './reducers'
//创建store仓库
const store = createStore(todoApp)
//createStore方法还可以接受第二个参数(),表示 State 的最初状态。这通常是服务器给出的(window.STATE_FROM_SERVER就是整个应用的状态初始值)
const store = createStore(todoApp, window.STATE_FROM_SERVER)
//引入action
import {
addTodo,
toggleTodo,
setVisibilityFilter,
VisibilityFilters
} from './actions'
//打印当前状态
console.log(store.getState())
// 订阅state变化
// subscribe()方法返回一个函数用于取消监听
const unsubscribe = store.subscribe(() => console.log(store.getState()))
// 发出一些action
store.dispatch(addTodo('Learn about actions'))
store.dispatch(addTodo('Learn about reducers'))
store.dispatch(addTodo('Learn about store'))
store.dispatch(toggleTodo(0))
store.dispatch(toggleTodo(1))
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED))
//取消监听状态更新
unsubscribe()
配置中间件
import { createStore } from 'redux'
import reducer from '../reducer/index'
import thunk from 'redux-thunk'
import promise from 'redux-promise'
import logger from 'redux-logger'
const store = createStore(
reducer,
applyMiddleware(thunk, promise, logger)
);
redux-thunk
store.dispatch()只能传入一个action对象,redux-thunk中间件则将其扩展为一个方法
//配置
import { createStore } from 'redux'
import reducer from '../reducer/index'
import thunk from 'redux-thunk'
const store = createStore(
reducer,
applyMiddleware(thunk)
);
//使用
export function getDocMenu(query='') {
return async(dispatch) => {
try {
const data = (await axios(`${baseUrl}doc.do?${Qs.stringify(query)}`)).data;
//这里的dispatch相当于store.dispatch
dispatch({
type: GET_PRODUCT_DOCUMENT_SUCCESS,
data: data
})
}
catch(error){
dispatch({
type: GET_PRODUCT_DOCUMENT_FAILURE,
error: new Error('获取文档菜单失败')
})
}
}
}
redux-saga
解决异步的另一种方法
//配置
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducer from './reducers'
import mySaga from './sagas'
// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
// mount it on the Store
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
)
// then run the saga
sagaMiddleware.run(mySaga)
//使用
// action creators
export function GET_USERS(users) {
return { type: RECEIVE_USERS, data }
}
export function GET_ERROR(error) {
return { type: FETCH_USERS_ERROR, data }
}
export function Begin_GET_POSTS() {
return { type: BEGIN_GET_POSTS }
}
//saga.js
import { takeEvery } from 'redux-saga';
import { call, put } from 'redux-saga/effects';
import axios from 'axios';
import { BEGIN_GET_POSTS, GET_POSTS, GET_POSTS_ERROR } from '../reducers';
// worker saga
function* showPostsAsync(action) {
try {
const response = yield call(axios.get, 'https://jsonplaceholder.typicode.com/posts');
yield put({
type: GET_POSTS,
data: response.data
});
} catch(e) {
yield put({
type: GET_ERROR,
error: new Error('some error')
});
}
}
// wacther saga
function* watchGetPosts() {
yield takeEvery(BEGIN_GET_POSTS, showPostsAsync);
}
// root saga
export default function* rootSaga() {
yield watchGetPosts()
}
//user.js
componentWillMount() {
this.props.dispatch(Begin_GET_POSTS());
}
Redux概览的更多相关文章
- 【原】整理的react相关的一些学习地址,包括 react-router、redux、webpack、flux
因为平时经常去网上找react相关的一些地址,找来找去很麻烦,所以自己整理了一下,不过前面部分不是我整理的, 是出自于:http://www.cnblogs.com/aaronjs/p/4333925 ...
- React Redux学习笔记
React Router React Router 使用教程 Redux中间件middleware [译]深入浅出Redux中间件 Redux学习之一:何为middleware? ES6 ES6新特性 ...
- Redux系列x:源码解析
写在前面 redux的源码很简洁,除了applyMiddleware比较绕难以理解外,大部分还是 这里假设读者对redux有一定了解,就不科普redux的概念和API啥的啦,这部分建议直接看官方文档. ...
- React Hooks实现异步请求实例—useReducer、useContext和useEffect代替Redux方案
本文是学习了2018年新鲜出炉的React Hooks提案之后,针对异步请求数据写的一个案例.注意,本文假设了:1.你已经初步了解hooks的含义了,如果不了解还请移步官方文档.(其实有过翻译的想法, ...
- RxJS + Redux + React = Amazing!(译一)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...
- 通过一个demo了解Redux
TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...
- RxJS + Redux + React = Amazing!(译二)
今天,我将Youtube上的<RxJS + Redux + React = Amazing!>的后半部分翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: ht ...
- redux学习
redux学习: 1.应用只有一个store,用于保存整个应用的所有的状态数据信息,即state,一个state对应一个页面的所需信息 注意:他只负责保存state,接收action, 从store. ...
- webpack+react+redux+es6开发模式
一.预备知识 node, npm, react, redux, es6, webpack 二.学习资源 ECMAScript 6入门 React和Redux的连接react-redux Redux 入 ...
随机推荐
- [HDOJ] 1172.猜数字
Problem Description 猜数字游戏是gameboy最喜欢的游戏之一.游戏的规则是这样的:计算机随机产生一个四位数,然后玩家猜这个四位数是什么.每 猜一个数,计算机都会告诉玩家猜对几个数 ...
- halcon视频教程如何学习?怎么样才能踏入机器视觉这个行业?
本人是工作八年的视觉工程师,主要从事Halcon和Visionpro视觉开发,谈谈个人对视觉学习看法: 1.HALCON是德国MVtec公司开发的一套完善的标准的机器视觉算法包,它节约了产品成本,缩短 ...
- http的无状态
无状态协议是指协议对务处理没有记忆能力.缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大.另一方面,在服务器不需要先前信息时它的应答就较快. Http协议不 ...
- JS原生隐士标签扩展
最近项目开发中,开发了不少的接口,有一个接口是这样子的.先从A公司拿到数据后,存放到我们公司数据库里,然后需要将数据展示给客户,下面这个界面,后台要实时刷新,后台写了个定时器,2S刷一次从后台拼接好H ...
- TestNG中group的用法
TestNG中的组可以从多个类中筛选组属性相同的方法执行. 比如有两个类A和B,A中有1个方法a属于组1,B中有1个方法b也属于组1,那么我们可以通过配置TestNG文件实现把这两个类中都属于1组的方 ...
- About dycf
SYSU 数媒在读 所有资料可能与课程相关可能与参与项目相关 欢迎交流 . . . 中之人: ↓↓↓ ↑↑↑ 是他 就是他 ↑↑↑
- 记一次idea问题—performing vcs refresh...
01.前言 本人出现该场景是,我把本地SVN A项目删了,而A项目与B项目同在一个SVN目录下,当我修改B项目且提交代码时,出现了该问题. idea不是很懂操作,就搜索了一下得出了三种答案,但只有其一 ...
- 二进制文件安装安装flannel
二进制文件安装安装flannel overlay网络简介 覆盖网络就是应用层网络,它是面向应用层的,不考虑或很少考虑网络层,物理层的问题. 详细说来,覆盖网络是指建立在另一个网络上的网络.该网络中的结 ...
- .NET Core CSharp 中级篇 2-2 List,ArrayList和Dictionary
.NET Core CSharp 中级篇 2-2 本节内容为List,ArrayList,和Dictionary 简介 在此前的文章中我们学习了数组的使用,但是数组有一个很大的问题就是存储空间不足,我 ...
- 手动编译PHP开发环境
目录 手动编译PHP开发环境 问题复盘 部署环境及配置 目标环境 安装部署环境开始 首先安装PHP 安装mysql 安装nginx 手动编译PHP开发环境 这是一篇来自深夜加班的手稿 问题复盘 你有没 ...