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)
  }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM