React:快速上手(7)——使用中间件实现异步操作

React:快速上手(7)——使用中间件实现异步操作

本文参考链接:Stack Overflow

redux-thunk

  我们使用store.dispath进行派发时,只能传递一个普通对象进去,如下:

store.dispatch({ type: 'INCREMENT' })

  但是,在使用redux-thunk中间件后,我们就可以传递一个函数进去

import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'

const store = createStore(
  reducer,
  applyMiddleware(thunk)
)

store.dispatch(function (dispatch) {
  // ... which themselves may dispatch many times
  dispatch({ type: 'INCREMENT' })
  dispatch({ type: 'INCREMENT' })
  dispatch({ type: 'INCREMENT' })

  setTimeout(() => {
    // ... even asynchronously!
    dispatch({ type: 'DECREMENT' })
  }, 1000)
})

  启用此中间件后,如果您dispatch一个函数,Redux Thunk中间件会将dispatch作为参数传进该函数中去。在这个函数中,我们派发了多个action,甚至可以异步执行一些操作,比如延迟1000ms,派发action。那我们执行异步操作,就是通过这个中间件来实现的。 

Action Creator

  我们最好把action封装到函数中,即(Action Creater),来提高灵活性以及防止我们拼写错误。对于对象,我们可以直接如下写:

function showNotification(id, text) {
  return { type: 'SHOW_NOTIFICATION', id, text }
}
function hideNotification(id) {
  return { type: 'HIDE_NOTIFICATION', id }
}

  那么这样一个函数式的action,我们也可以将其封装到一个函数中,它返回一个函数式的action

let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
  return function (dispatch) {
    const id = nextNotificationId++
    dispatch(showNotification(id, text))

    setTimeout(() => {
      dispatch(hideNotification(id))
    }, 5000)
  }
}

  那么,我们在调用它的时候是需要手动传入一个dispatch的。

showNotificationWithTimeout('You just logged in.')(this.props.dispatch)

  如果启用了Redux Thunk中间件,则只要你尝试dispatch函数而不是对象,中间件就会使用调度方法本身作为第一个参数来调用该函数,也就是我们可以这样写:

// component.js
this.props.dispatch(showNotificationWithTimeout('You just logged in.'))

配合React Redux的connect

  Redux可以自动识别出这样的“特殊”Action Creator(我们称之为Thunk Action Creator),我们现在可以在任何我们使用常规动作创建者的地方使用它们。例如,我们可以将它们与connect()一起使用:

// actions.js

function showNotification(id, text) {
  return { type: 'SHOW_NOTIFICATION', id, text }
}
function hideNotification(id) {
  return { type: 'HIDE_NOTIFICATION', id }
}

let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
  return function (dispatch) {
    const id = nextNotificationId++
    dispatch(showNotification(id, text))

    setTimeout(() => {
      dispatch(hideNotification(id))
    }, 5000)
  }
}

// component.js

import { connect } from 'react-redux'

// ...

this.props.showNotificationWithTimeout('You just logged in.')

// ...

export default connect(
  mapStateToProps,
  { showNotificationWithTimeout }
)(MyComponent)

在thunk中获取状态

  Redux Thunk提供了一种方法来获取Redux store的state。除了dispatch之外,它还将getState作为第二个参数传递给您从thunk action creator返回的函数。这让thunk读取store的当前state。

let nextNotificationId = 0
export function showNotificationWithTimeout(text) {
  return function (dispatch, getState) {
    // Unlike in a regular action creator, we can exit early in a thunk
    // Redux doesn’t care about its return value (or lack of it)
    if (!getState().areNotificationsEnabled) {
      return
    }

    const id = nextNotificationId++
    dispatch(showNotification(id, text))

    setTimeout(() => {
      dispatch(hideNotification(id))
    }, 5000)
  }
}

  

posted @ 2019-03-12 22:52  子烁爱学习  阅读(934)  评论(0编辑  收藏  举报