• redux-thunk 简单案例,优缺点和思考


    redux-thunk

    实现一个异步的加数器

    框架为: react + react-redux + redux-thunk

    项目结构

    在这里插入图片描述

    代码如下

    新建一个 component -> App.js , 代码如下

    // App.js
    import '@babel/polyfill'
    import * as React from 'react'
    import { render } from 'react-dom'
    import { Provider } from 'react-redux'
    import Index from './Index'
    import { createStore, applyMiddleware } from 'redux'
    import thunk from 'redux-thunk'
    import rootReducer from '../reducers'
    
    const enhancer = applyMiddleware(thunk);
    const configureStore = createStore(
      rootReducer,
      enhancer
    );
    function Main() {
        return <Provider store={configureStore}>
        <Index />
      </Provider>
    }
    export default Main
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Services

    新建 services -> index.js , 接口层

    export function getData(){
        return Promise.resolve({num:1})
    }
    
    • 1
    • 2
    • 3

    Actions

    新建 actions -> index.js

    
    export const ADD_COUNT = 'ADD_COUNT'
    export const ADD_COUNT_ASYNC = 'ADD_COUNT_ASYNC'
    export const DECREASE_COUNT = 'DECREASE_COUNT'
    import {getData} from '../services/index'
    export function add_count(num) {
        return {
          type: ADD_COUNT,
          num,
        }
    }
    export const add_count_sync = () => (dispatch) => {
        setTimeout(() => {
            getData().then(res => {
                console.log(res)
                const { num } = res;
                dispatch(add_count(num));
            })
        }, 1000);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Reducers

    新建 reducers -> index.js

    // index.js
    import { combineReducers } from 'redux';
    function count_change(state = 0, action = {}) {
        console.log(action)
        switch (action.type) {
            case 'ADD_COUNT':
                state = state + action.num
                break;
            default:
                break;
        }
        return state
    }
    export default combineReducers({
        count_change
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Components

    新建一个 components -> Index.js

    import React from 'react' 
    import {connect} from 'react-redux'
    import {add_count , add_count_sync} from '../actions/index'
    import {getData} from '../services/index'
    function Index(props) {
        return <div>
            当前数据 {props.state} <br></br>
            <button onClick={()=>{
                props.add_count_sync()
            }}>点击我</button>
        </div>
    }
    const mapStateToProps = function(store) {
        return {
            state: store.count_change
        }
    }
    export default connect(mapStateToProps,{add_count_sync})(Index)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Redux-thunk 优缺点总结

    优点

    1. 代码简洁明了
    2. 库代码量小

    缺点

    1. 由于先调用的是接口层,导致代码可能会特别臃肿 , 设想一个例子
    如果一个接口既需要触发 action 的 `A1` ,而且还需要触发 `A2`,
    这样子可能会使得接口在异步的时候需要判断需要触发哪个 action , 会使得代码难以维护
    
    • 1
    • 2

    补充

    最新看了下大佬一些 blog, 顺便看了下 react-thunk 源码 , 只有非常简单的几句话,就是一个 柯理化函数

    // node_modules\redux-thunk\es\index.js
    
    /** A function that accepts a potential "extra argument" value to be injected later,
     * and returns an instance of the thunk middleware that uses that value
     */
    function createThunkMiddleware(extraArgument) {
      // Standard Redux middleware definition pattern:
      // See: https://redux.js.org/tutorials/fundamentals/part-4-store#writing-custom-middleware
      var middleware = function middleware(_ref) {
        var dispatch = _ref.dispatch,
            getState = _ref.getState;
        return function (next) {
          return function (action) {
            // The thunk middleware looks for any functions that were passed to `store.dispatch`.
            // If this "action" is really a function, call it and return the result.
            // action 其实就是我们的 动态 antion
            if (typeof action === 'function') {
              // Inject the store's `dispatch` and `getState` methods, as well as any "extra arg"
              return action(dispatch, getState, extraArgument);
            } // Otherwise, pass the action down the middleware chain as usual
    
    
            return next(action);
          };
        };
      };
    
      return middleware;
    }
    var thunk = createThunkMiddleware(); // Attach the factory function so users can create a customized version
    // with whatever "extra arg" they want to inject into their thunks
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    思考

    这里有个 问题 , 其实上诉的 方法 不用 react-thunk , 也能实现 , 完全不用去实现 asyncAction ,而且 action 也是 pure

    const mapDispatchToProps = (dispatch) => {
        return {
          getMenuTreeFn:  () => {
            setTimeout(() => {
                getData().then(res => {
                    console.log(res)
                    const { num } = res;
                    dispatch(add_count(num));
                  })
            }, 5000);
          }
        }
    }
    export default connect(mapStateToProps,mapDispatchToProps)(Index)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    然后我找到这么一篇文章,

    Why do we need middleware for async flow in Redux?

    里面有个大佬的原话大概是:

    1. 为了更加贯彻 redux 的思想
    2. 而且 react-thunk 可以更好地调用 getState

    然后还修正了 action 必须是 pure 这段话,原话大概是:

    I searched the Redux repo for clues, and found that Action Creators were required to be pure functions in the past.

    This is incorrect. The docs said this, but the docs were wrong.
    Action creators were never required to be pure functions.
    We fixed the docs to reflect that.
    
    • 1
    • 2
    • 3

    如果理解有错,欢迎大佬斧正

  • 相关阅读:
    洛谷 P3128 最大流Max Flow
    SpringBoot如何集成Log模块呢?
    CCF CSP认证 历年题目自练Day35
    成都爱尔周进院长解读不同近视手术的不同度数要求
    Java版企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    [C++] std::format应用自定义类型
    UDS诊断:87服务-LinkControl(链接控制服务)
    基于小程序探索如何实现数字传媒内容价值最大化
    OceanBase 来参加外滩大会了(内附干货PPT)
    <学习笔记>从零开始自学Python-之-基础语法篇(九)类的继承与多态
  • 原文地址:https://blog.csdn.net/weixin_38992765/article/details/125404885