开发文档

源码

代码已经上传到github中,欢迎star或者fork

appstore-react-v2.0

redux-saga

一、介绍

之前异步处理用的是redux-thunk + redux-actions + redux-promise,但是随着ES6中Generator的出现,人们发现用Generator处理异步可以更简单。而redux-saga就是用Generator来处理异步。

redux-saga文档并没有说自己是处理异步的工具,而是说用来处理边际效应(side effects),这里的边际效应你可以理解为程序对外部的操作,比如请求后端,比如操作文件。

redux-saga同样是一个redux中间件,它的定位就是通过集中控制action,起到一个类似于MVC中控制器的效果。

同时它的语法使得复杂异步操作不会像promise那样出现很多then的情况,更容易进行各类测试。

二、 安装

npm install --save redux-saga

三、saga常用辅助函数

put、call、takeEvery、takeLatest

1、put和call

put相当于redux的dispatch的作用,而call相当于调用函数

export function* delayChangeBtnText() {
yield delay(1000);
yield put(changeBtnText('123'));
yield call(consoleMsg, '完成改变');
}
2、takeEvery

它提供了类似 redux-thunk 的行为

import { takeEvery } from 'redux-saga'

function* watchFetchData() {
yield* takeEvery('FETCH_REQUESTED', fetchData)
}
3、takeLatest

takeEvery 允许多个 fetchData 实例同时启动。在某个特定时刻,尽管之前还有一个或多个 fetchData 尚未结束,我们还是可以启动一个新的 fetchData 任务,

如果我们只想得到最新那个请求的响应(例如,始终显示最新版本的数据)。我们可以使用 takeLatest辅助函数

import { takeLatest } from 'redux-saga'

function* watchFetchData() {
yield* takeLatest('FETCH_REQUESTED', fetchData)
}

四、使用

1、修改store/index.js
import { createStore, applyMiddleware } from 'redux';
// import thunk from 'redux-thunk';
import createSagaMiddleware from 'redux-saga';
import {watchAppSearch} from './sagas';
import rootReducer from './reducers'; /**
* saga用法
* 1.创建一个 Saga middleware
* 2.使用 applyMiddleware 将 middleware 连接至 Store
* 3.使用 sagaMiddleware.run(helloSaga) 运行 Saga
*/
const sagaMiddleware = createSagaMiddleware(); // 创建store的时候,第二个参数是中间件,redux-thunk提供了一个thunk中间件,用于处理异步的action
let store = createStore(
rootReducer,
applyMiddleware(sagaMiddleware)
); // 运行并监控各个action
sagaMiddleware.run(watchAppSearch); export default store
2、创建store/sagas.js
import { put, call, takeEvery,takeLatest } from 'redux-saga/effects';
import { actionCreators } from './action'
import $api from '../api/index.js';
/**
* 处理编辑效应的函数
*/
export function* appSearch(action) {
// 在saga中这里通过action.payload获取到前台传过来的keyword内容
const p = function(){
return $api.lookUp({
keyword:action.payload
})
.then(res => res.results)
.then(res =>{
return res
})
}
const res = yield call(p); // 执行p函数,返回值赋值给res
yield put(actionCreators.saveSearchList(res));// 通过put触发dispatch ,将返回数据传过去
}
/**
* 监控Action的函数
*/
// takeLatest 和 takeEvery 不同,在任何时刻 takeLatest 只允许一个 fetchData 任务在执行。
// 并且这个任务是最后被启动的那个。 如果已经有一个任务在执行的时候启动另一个 fetchData ,那之前的这个任务会被自动取消。
export function* watchAppSearch() {
yield takeEvery(actionCreators.appSearch, appSearch);
}
3、同时启动多个Sagas 监听action动作
// 同时启动多个Sagas  监听action动作
export default function* rootSaga() {
yield all([
takeLatest(actionCreators.appSearch, appSearch),
takeLatest(actionCreators.getRecommendList, getRecommendList)
])
} /**
* app搜索获取结果列表
*/
export function* appSearch(action) {
// 在saga中这里通过action.payload获取到前台传过来的keyword内容
const p = function(){
return $api.lookUp({
keyword:action.payload
})
.then(res => res.results)
.then(res =>{
return res
})
}
const res = yield call(p); // 执行p函数,返回值赋值给res
yield put(actionCreators.saveSearchList(res));// 通过put触发dispatch ,将返回数据传过去
} /**
* 请求获取推荐列表
* @param {*} action
*/
export function* getRecommendList(action) {
const p = function(){
return $api.recommendData({})
.then(res => res.feed)
.then(res =>{
return res
})
}
const res = yield call(p); // 执行p函数,返回值赋值给res
yield put(actionCreators.getRecommendListSucceeded(res.entry));
}

redux-actions

redux-actions用来简化redux重复代码,这部分简化工作主要集中在构造action和处理reducers方面。

一、安装

npm install --save redux-actions

二、使用

-----action.js
import * as types from './action-types'
import { createActions } from 'redux-actions'; /**
* 使用redux-actions之前
*/
// export const saveSearchList = (searchList) => {
// console.log('searchList',searchList)
// return {
// type: types.SAVE_SERACH_LIST,
// searchList
// }
// } // export const removeSearchList = () => {
// return {
// type: types.REMOVE_SERACH_LIST
// }
// } /**
* 使用redux-actions之后
*/
// 使用createAction创建单个动作
// export const saveSearchList = createAction(types.SAVE_SERACH_LIST,searchList=>searchList);
// export const removeSearchList = createAction(types.REMOVE_SERACH_LIST); // 使用createActions创建多个动作
export const actionCreators = createActions({
[types.SAVE_SEARCH_LIST]:searchList=>searchList,
[types.REMOVE_SEARCH_LIST]:()=>null
});
-----reducer.js
import * as types from './action-types'
import { handleActions } from 'redux-actions'; let defaultState = {
searchList: []//搜索结果列表
} /**
* 使用redux-actions之前
*/
// 修改state
// export default(state = defaultState, action={})=>{
// switch (action.type) {
// case types.SAVE_SERACH_LIST:
// return {
// ...state,
// searchList: action.searchList
// }
// case types.REMOVE_SERACH_LIST:
// return{
// ...state,
// searchList:[]
// }
// default:
// return state
// }
// } /**
* 使用redux-actions之后
*/
// handleAction单个action处理
// const reducer = handleAction(types.SAVE_SERACH_LIST,(state, action)=>{
// return {
// ...state,
// searchList: action.searchList
// }
// },defaultState); // 使用handleActions处理多个actions ,这里需要注意的是 通过action.payload获取传过来的数据
const reducerCreators = handleActions({
[types.SAVE_SEARCH_LIST]:(state, action)=>{
return {
...state,
searchList: action.payload
}
},
[types.REMOVE_SEARCH_LIST]:(state, action)=>{
return{
...state,st
searchList:[]
}
}
},defaultState); export default reducerCreators;
---index.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { actionCreators } from '../../store/action'
/**
* 使用redux-action之前
*/
// const mapDispatchToProps = (dispatch) => ({
// 分发由action creators创建的actions
// saveSearchList: searchList => dispatch(saveSearchList(searchList)),
// removeSearchList: () => dispatch(removeSearchList())
// }) /**
* 使用redux-action之后
*/
// createActions会返回一个对象,对象针对每个action类型都有一个值为action工厂的属性,属性名为action类型的值去掉下划线后的驼峰命名
const mapDispatchToProps = {
saveSearchList:actionCreators.saveSearchList,
removeSearchList:actionCreators.removeSearchList
} // 通过connect生成容器组件
export default connect(mapStateToProps,mapDispatchToProps)(SearchResult);

源码

代码已经上传到github中,欢迎star或者fork

appstore-react-v2.0

参考阅读

最新文章

  1. python写红包的原理流程包含random,lambda其中的使用和见简单介绍
  2. ubuntu 13.04 telnet 详细配置
  3. mysql入门教程
  4. Javascript中对象的Obeject.defineProperty()方法-------------(ES5/个人理解)
  5. JS表单验证类HTML代码实例
  6. 万事开头难——Cocos2d-x学习历程(一)
  7. QT学习 之 三维饼图绘制
  8. VUE2.0实现购物车和地址选配功能学习第七节
  9. CentOS7.3安装NVIDIA-1080ti驱动、cuda、cudnn、TensorFlow
  10. 'gbk' codec can't encode character解决方法
  11. 【原创】运维基础之Docker(2)通过docker部署zookeeper nginx tomcat redis kibana/elasticsearch/logstash mysql kafka mesos/marathon
  12. How to create ISO on macOS
  13. 跟随我在oracle学习php(8)
  14. centos6 -> zabbix2.2升级3.0.5教程
  15. 救基友3(三维BFS)
  16. Entity Framework中IQueryable, IEnumerable, IList的区别(转载)
  17. bootstrap collaspe
  18. 评分卡模型中的IV和WOE详解
  19. (Android+IOS)正在做一个新闻App,做的差不多了,听听大家的建议 (图)
  20. 使用ESP8266连接到Azure

热门文章

  1. PHPStorm使用PHP7新特性出现红色波浪错误
  2. tomcat9上传文件失败错误
  3. oracle学习笔记(十六) PL/SQL 异常和goto语句
  4. C# download big file
  5. 用 Python 监控知乎和微博的热门话题
  6. JAVA----HelloWorld
  7. Redis哨兵模式大key优化
  8. 第三方库Mantle的简单实用
  9. Smobiler针对百度文字识别SDK动态编译与运行
  10. NSCach 的知识小记