《三》redux-thunk 中间件

在之前的代码中,必须将网络请求的异步代码放到组件的生命周期中来完成。

// increase.js
import React, {PureComponent} from 'react'
import {connect} from 'react-redux'
import axios from 'axios'
import {increaseAction} from '../store/action'

class Increase extends PureComponent {
  handleIncrease = () => {
  	// 网络请求的异步代码
    axios.get('http://123.207.32.32:8000/home/multidata').then(res => {
      const count = res.data.data.banner.list.length
      this.props.handleCountIncrease(count)
    })
  }

  render() {
    return (
      
) } } const mapDispatchToProps = dispatch => ({ handleCountIncrease: count => { dispatch(increaseAction(count)) } }) export default connect(null, mapDispatchToProps)(Increase)

但实际上,网络请求到的数据也属于状态管理的一部分,更好的做法是将它们也交给 Redux 来管理。

由于 Action 是一个对象,所以无法在 Action 中进行网络请求; Reducer 是一个纯函数,不能有副作用,所以也不能在 Reducer 中进行网络请求。因此只能尝试对 dispatch() 进行处理。
《三》redux-thunk 中间件_第1张图片

Redux 中间件:

Redux 引入了中间件 Middleware 的概念。

Redux 中间件的核心是在 dispatch 之后,到达 Reducer 之间进行一些扩展。原理是对 Redux 的 dispatch 进行了一层封装,主要是增强 dispatch 的能力。可以利用 Redux 中间件来进行日志记录(redux-logger)、执行异步操作(redux-thunk)等。

没有中间件:store.dispatch() 就是 Redux 自己的 dispatch 方法,用来发起状态更新。dispatch() => reducer。
使用中间件:store.dispatch() 就是中间件封装后的 dispatch,但是最终还是一定会调用 Redux 自己的 dispatch 方法发起状态更新。dispatch() => 执行中间件代码 => reducer。

在 Redux 中注册中间件。

// 以 redux-thunk 为例
// 1. 从 redux 中引入 applyMiddleware 方法,以逗号分割可传入多个中间件
import {createStore, applyMiddleware} from 'redux'
// 2. 从 react-thunk 中引入中间件 thunk
import thunk from 'redux-thunk'
import reducer from './reducer'

// 3. createStore() 可传入第二个参数来注册中间件,对 dispatch 进行增强
export default createStore(reducer, applyMiddleware(thunk))

redux-thunk

redux-thunk 的主要功能就是可以让 dispatch 派发一个函数,那么,就可以在这个函数内部做任何事情了(例如:进行网络请求等)。因此,通常使用 redux-thunk 中间件来处理异步操作。

Redux 中的 dispatch 正常情况下只能派发一个对象。

redux-thunk 的核心代码其实就是判断每个经过它的 action:如果是 function 类型,就调用这个 function,而不是任由让它到达 reducer。因为 reducer 是个纯函数,Redux 规定到达 reducer 的 action 必须是一个 plain object 类型。

安装:

npm install redux-thunk

使用:
  1. 注册 redux-thunk 中间件来对 dispatch 进行增强。
    // store/index.js
    // 从 redux 中引入 applyMiddleware 方法,以逗号分割可传入多个中间件
    import {createStore, applyMiddleware} from 'redux'
    // 从 react-thunk 中引入中间件 thunk
    import thunk from 'redux-thunk'
    import reducer from './reducer'
    
    // createStore() 可传入第二个参数来注册中间件,对 dispatch 进行增强
    export default createStore(reducer, applyMiddleware(thunk))
    
  2. 在组件中,通过 store.dispatch() 派发的时候派发一个函数,该函数会被自动执行,并传入 dispatch 和 getState 两个方法作为其参数,在函数内部执行完异步操作之后,再通过 dispatch 参数派发一个 Action 对象。

    也就是说,开始派发的函数的作用只是可以在其内部进行异步操作,最终派发出去的仍然是一个 Action 对象,Reducer 会在接收到该 Action 后返回最新的 State。

    // increase.js
    import React, {PureComponent} from 'react'
    import {connect} from 'react-redux'
    import {increaseAction} from '../store/action'
    
    class Increase extends PureComponent {
      handleIncrease = () => {
        this.props.handleCountDecrease()
      }
    
      render() {
        return (
          
    ) } } const mapDispatchToProps = dispatch => ({ handleCountDecrease: () => { // store.dispatch() 派发一个函数,派发的函数会被自动执行 dispatch(increaseAction()) } }) export default connect(null, mapDispatchToProps)(Increase)
    // store/action.js
    import axios from 'axios'
    
    // 创建 Action 的 Action Creator
    export const increaseAction = () => {
      // 派发的函数会接收 Store 中的 dispatch 和 getState 两个方法作为参数
      return (dispatch, getState) => {
        axios.get('http://123.207.32.32:8000/home/multidata').then(res => {
          const count = res.data.data.banner.list.length
          // 在派发的函数内部执行完异步操作之后,再通过 dispatch 派发一个 Action 对象
          dispatch({
            type: 'increase',
            count,
          })
        })
      }
    }
    

你可能感兴趣的:(Redux,Redux)