appstore-react v2.0-redux-actions and redux-saga applications

Development Documentation

  • https://redux-saga.js.org/
  • https://redux-saga-in-chinese.js.org/
  • https://redux-actions.js.org/

Source

Code has been uploaded to github welcomed star or fork

appstore-react-v2.0

redux-saga

I. INTRODUCTION

Before processing the asynchronous redux-thunk + redux-actions + redux-promise, but with the advent of the Generator ES6, it was found easier to handle asynchronous be used Generator. And redux-saga is treated with asynchronous Generator.
redux-saga document does not say that they are asynchronous processing tool, but that used to deal with marginal effects (side effects), the marginal effect here you can understand the operation of the external program, such as the back-end requests, such as file operations.
redux-saga is also a redux middleware, its position is controlled by a centralized Action, functions as a controller similar to the effect of MVC.
While its syntax makes complex asynchronous operation does not appear then as many cases as promise, easier to carry out all kinds of tests.

Second, the installation

npm install --save redux-saga

Three, saga common helper

put、call、takeEvery、takeLatest

1、put和call

put equivalent to the role of dispatch redux, while the call is equivalent to calling the function

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

It provides a similar redux-thunk behavior

import { takeEvery } from 'redux-saga'

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

takeEvery fetchData allows multiple instances started simultaneously. At a given moment, although there are one or more fetchData not over before we can start a new fetchData task,
if we want to get the latest response to the request (for example, always shows the latest version of the data). We can use takeLatest Helper

import { takeLatest } from 'redux-saga'

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

Fourth, the use

1, modified 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, create a 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, start multiple Sagas monitor action 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 redux-actions to simplify the code repetition, this work focuses on simplifying part construction and action processing aspects reducers.

First, install

npm install --save redux-actions

Second, the use

-----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);

Source

Code has been uploaded to github welcomed star or fork

appstore-react-v2.0

Reference Reading

  • https://juejin.im/post/5b41641ef265da0f8202126d
  • https://www.jianshu.com/p/d2615a7d725e
  • https://segmentfault.com/a/1190000017064759?utm_source=tag-newest

Guess you like

Origin www.cnblogs.com/fozero/p/11570230.html