• appstore-react v2.0—redux-actions和redux-saga的应用


    开发文档

    源码

    代码已经上传到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

    参考阅读

  • 相关阅读:
    iptables一个包过滤防火墙实例
    www的iptables实例
    iptables单个规则实例
    iptables [-j target/jump] 常用的处理动作
    iptables [match] 常用封包匹配参数
    iptables command 常用命令列表
    iptables [-t table] 指定规则表
    iptablesIP规则的保存与恢复
    iptables在我们的网络机房实现NAT共享上网
    iptables典型NAT上网
  • 原文地址:https://www.cnblogs.com/fozero/p/11570230.html
Copyright © 2020-2023  润新知