关于 redux-thunk 的作用,认识,理解

看这篇文章之前,如果你已经看到一些 redux-thunk 的教程,是不是觉得一头雾水,redux-thunk 到底有什么作用,用在哪里,代码不仅没有简化,反而还增加?基于我初学的一些疑惑和后来疯狂的百度,总结了一下

首先来一段代码示例

如果我们有一个异步请求,获取数据展示在页面上。假设 redux 都是已经写好了。我们只模拟请求阶段

// App.js
import React, { Component } from 'react'
import store from './store/index'
import axios from 'axios'class App extends Component {constructor(props) {super(props)this.state = store.getState()// store 监听更新,并且自动赋值到页面上store.subscribe(() => this.setState(store.getState()))}// 在页面组件挂载后,请求一个模拟的接口,获取一个todoList列表componentDidMount() {axios.get('http://rap2.taobao.org:38080/app/mock/246209/todoList').then(res => {store.dispatch({ type: 'GET_LIST', value: res.data.data })}).catch(res => {})}render() {return (<ul>{this.list.map((item, index) => {return <li key={index}>{item}</li>})}</ul>)}
}export default App

先来看下这段代码有什么问题:

  1. 在生命周期函数中请求了一个接口,那如果这个页面渲染需要多个接口呢,那生命周期代码量就会非常的大(可以把这些请求抽成方法啊,然后生命周期中只调用方法就简洁了)。没错,写成方法真是我们要做的

  2. 不利于测试,在我们没写成方法之前,如果我们想单元测试下这个接口,模拟一些数据,我们很难在生命周期中模拟


使用 redux-thunk 来优化代码

新建一个 js 文件,来统一放我们请求/操作的代码

  • 我们定义一个 getTodoList 方法
// src/store/actionCreators.js// 这个方法看上去像一个闭包。因为redux-thunk是可以接收一个函数的,所以我们来返回一个函数
export const getTodoList = () => {return dispatch => {axios.get('http://rap2.taobao.org:38080/app/mock/246209/todoList').then(res => {console.log(res.data.data)dispatch({ type: GET_LIST, value: res.data.data })}).catch(res => {})}
}
  • 在 App.js 页面上使用
// App.js
import React, { Component } from 'react'
import store from './store/index'
// ! 异同 ! 这里我们不在需要引入axios。而是引入我们的方法
import { getTodoList } from './store/actionCreators'class App extends Component {constructor(props) {super(props)this.state = store.getState()// store 监听更新,并且自动赋值到页面上store.subscribe(() => this.setState(store.getState()))}componentDidMount() {// ! 异同 ! 这里还是在生命周期获取数据。// 不过这里我们执行 getTodoList() 返回的是一个函数store.dispatch(getTodoList())}render() {return (<ul>{this.list.map((item, index) => {return <li key={index}>{item}</li>})}</ul>)}
}
export default App

对比着看,2 段代码没有什么不同,反而好像了些代码,那下面我们就来细细分析


redux-thunk 作用是什么

redux-thunk 可以让 store.dispatch 变成可以接收一个函数/一个对象的中间件

  • redux-thunk 源码
function createThunkMiddleware(extraArgument) {return ({ dispatch, getState }) => next => action => {if (typeof action === 'function') {return action(dispatch, getState, extraArgument)}return next(action)}
}const thunk = createThunkMiddleware()
thunk.withExtraArgument = createThunkMiddlewareexport default thunk

让原本只能接受对象的 store.dispatch 变成可以接收对象/方法,并且如果接收了一个方法后自动执行该方法,而不触发 redux 的 store 更新。

这有点拗口,来一个张图:

而且 redux-thunk 在执行我们的函数后,可以给我们返回 dispatch.在 redux-thunk 源码的第四行。那么我们可以在异步回调后直接拿到 dispatch 来继续派发我们的 redux 的事件,并且把异步函数抽象成了一个方法,使用 store.dispatch 来触发该方法。

譬如我们有一个加入购物车功能的接口,在商品详情可以加入购物车,在购物车可以添加商品的数量,那这个接口是可以复用的,抽离了之后,就可以在不同界面一起调用这个接口。从而实现代码复用

如果说 redux-thunk 是为了异步代码复用,为什么不定义一个方法调用,一定要用 redux-thunk 呢?

难道我们写成一个公共函数,然后在函数中引入 sotre 他不香吗?这样全部方法都可以获得 store 对象,也能调用 store.dispatch 方法来派发事件啊

这个事情要从 redux 设计说起:

  1. 它强制了 store 必须是一个单例:这对服务端渲染很不友好,因为对于不同的用户或者说请求,它都应该有个独立的 store

  2. 不易于测试:因为使用了外部引用的 store,你没办法方便地 mock 一个 store 用来测试,也不能控制 store 的状态

ps: 以上 2 短话摘录自:为什么要使用 redux-thunk。包括上面的图也是盗用这位大佬的。


总结

redux-thunk 的功能介绍就说道这里了。在刚开始学的时候,的确很难理解,明明代码没简化,还多引了一个插件,这到底图什么?

一切为了代码复用,可能代码量还少,看不出来优势,等到多个地方用到同一段代码,就知道代码复用是多爽的一件事,其次就是 redux-thunk 强化了 store.dispatch 方法。而且遵循了 redux强制store必须是一个单例的规则。也方便做局部测试

关于 redux-thunk 的作用,认识,理解相关推荐

  1. 对Java单例模式 volatile关键字作用的理解

    单例模式是程序设计中经常用到的,简单便捷的设计模式,也是很多程序猿对设计模式入门的第一节课.其中最经典的一种写法是: class Singleton {private volatile static ...

  2. self-attention的作用,理解

    Attention与Self Attention Self Attention也经常被称为intra Attention(内部Attention),最近一年也获得了比较广泛的使用,比如Google最新 ...

  3. 神经网络各个部分的作用 彻底理解神经网络

    这些题目来自知识星球[CV技术指南(免费版)]的日常作业 欢迎关注公众号CV技术指南,专注于计算机视觉的技术总结.最新技术跟踪.经典论文解读.CV招聘信息. 1. 神经网络的层数是如何数的? 我们说的 ...

  4. c语言中 引用的作用,阅读理解中古诗词引用的作用

    文章中引用古诗词的作用是什么 展开全部 作为一种常见修辞方法,通过在文章中有意引用诗句.名人事例.格言等,来表达自己的思想感情或看法. 它的作用主要包括:1.可使所表达的语言意思简洁凝练,增添感染力, ...

  5. Java中接口作用的理解

    关于Java中接口作用的深入理解.这是个很容易遇到的问题吧,看下面红色的部分应该就能理解了.要把接口视作一种共同规范. / 2019/3/1 补充 : 接口的存在也是为了弥补类无法多继承的缺点,假设一 ...

  6. python装饰器作用-如何理解Python装饰器?

    晚上失眠,怒上知乎答题! 刚好最近我的python专栏里写过一篇装饰器相关的,不说废话,直接上干货! /> 目录如下:1.装饰器是什么? 2.如何使用装饰器? 3.内置装饰器 一.装饰器是什么? ...

  7. mysql的分区技术作用_理解MySQL数据库分区管理的技术细节

    在MySQL数据库中,表的不同部分在不同的位置被存储为单独的表.分区主要就是用来解决表在不同的位置存储的问题.在其他数据库中,也会存在这种情况.他们将这种类型的数据表称之为分区表.分区的管理,对于My ...

  8. 有关l2,1范数作用的理解--正则化项作用,不同于l1范数(矩阵元素绝对值之和)的稀疏要求,l21范数还要求行稀疏

    今天和导师讨论问题的时候,说到了l21范数.导数希望我能解释一下,我明白它的作用可是我知道我没有向老师解释清楚,有些失落.今晚就自己总结一下吧,希望下次再有人问我这个问题的时候我能向别人解释清楚. 先 ...

  9. 匿名函数php作用,深入理解PHP中的匿名函数

    匿名函数的作用就是扩大函数的使用功能,在PHP(PHP培训 php教程 ) 5.3以前,传递Callback的方式,我们只有俩种选择: ◆字符串的函数名 ◆使用create_function的返回 在 ...

  10. 数据库连接池的作用及理解

    初识为什么要用连接池: 对于一个简单的数据库引用,用于对数据库的访问不是很频繁,这种情况可以简单的在需要访问数据库时,创建一个链接,用完关闭它,这样做不会有太明显的性能上的开销.但是对于复杂的数据库引 ...

最新文章

  1. SQL SERVER 导入EXCEL的存储过程
  2. c打印char* 数据_JAVA基础篇(数据类型)
  3. Forrester 最新报告:阿里云稳居领导者地位,引领云原生开发浪潮
  4. 2020-11-30 离散系统自适应控制中的一个关键性引理及证明
  5. python调换字符串顺序_python实现指定字符串交换
  6. 使用Github部署Azure应用服务
  7. 大整数乘法c语言代码_大整数乘法
  8. 机器学习预测+akshare
  9. Ubuntu 10.04 Beta 1发布
  10. oracle 表空间配置
  11. 昂达v891w可以用u盘linux,昂达V891W CH Windows10(TH2)系统镜像(适用于V1版本)下载...
  12. 控制系统设计专题(二)——自抗扰控制算法(上)
  13. 手机ppi排行测试软件,依然是目前屏幕色准表现最好的智能手机:iPhone XS 屏幕测试...
  14. 云计算未来的5个发展趋势分析
  15. 尚硅谷-SpringBoot1.5.9(已过时,直接学2)
  16. VScode淡绿色护眼设置
  17. 少儿思维能力培养受重视 掌门少儿优质课程产品广获家长青睐
  18. 利用ZXing工具生成二维码以及解析二维码
  19. Matlab缩放曲线局部窗口
  20. 01:入门篇 - 初识 CTK

热门文章

  1. 安卓手机如何直接跟Mac电脑互传文件
  2. python做数据分析时缺失值填补、缺失值填充方法汇总
  3. css textarea行数_超级简单:在一个TextArea中如何限制行数和字符数
  4. 笔记:[windows] 简单写一个cmd命令行可执行的脚本.bat
  5. java关闭事件_为Java程序添加退出事件
  6. Flutter事件分发
  7. 微信授权时遇到48001的问题
  8. 康复医疗 趋势引领新蓝海
  9. 在OpenCV里实现二维离散卷积1
  10. C# CultureInfo列表