How to dispatch a Redux action with a timeout?

后端 未结 12 1935
花落未央
花落未央 2020-11-22 04:14

I have an action that updates the notification state of my application. Usually, this notification will be an error or info of some sort. I need to then dispatch another act

12条回答
  •  滥情空心
    2020-11-22 04:50

    A repository with sample projects

    Current there are four sample projects:

    1. Writing Async Code Inline
    2. Extracting Async Action Creator
    3. Use Redux Thunk
    4. Use Redux Saga

    The accepted answer is awesome.

    But there is something missing:

    1. No runnable sample projects, just some code snippets.
    2. No sample code for other alternatives, such as:
      1. Redux Saga

    So I created the Hello Async repository to add the missing things:

    1. Runnable projects. You can download and run them without modification.
    2. Provide sample code for more alternatives:
      • Redux Saga
      • Redux Loop
      • ...

    Redux Saga

    The accepted answer already provides sample code snippets for Async Code Inline, Async Action Generator and Redux Thunk. For the sake of completeness, I provide code snippets for Redux Saga:

    // actions.js
    
    export const showNotification = (id, text) => {
      return { type: 'SHOW_NOTIFICATION', id, text }
    }
    
    export const hideNotification = (id) => {
      return { type: 'HIDE_NOTIFICATION', id }
    }
    
    export const showNotificationWithTimeout = (text) => {
      return { type: 'SHOW_NOTIFICATION_WITH_TIMEOUT', text }
    }
    

    Actions are simple and pure.

    // component.js
    
    import { connect } from 'react-redux'
    
    // ...
    
    this.props.showNotificationWithTimeout('You just logged in.')
    
    // ...
    
    export default connect(
      mapStateToProps,
      { showNotificationWithTimeout }
    )(MyComponent)
    

    Nothing is special with component.

    // sagas.js
    
    import { takeEvery, delay } from 'redux-saga'
    import { put } from 'redux-saga/effects'
    import { showNotification, hideNotification } from './actions'
    
    // Worker saga
    let nextNotificationId = 0
    function* showNotificationWithTimeout (action) {
      const id = nextNotificationId++
      yield put(showNotification(id, action.text))
      yield delay(5000)
      yield put(hideNotification(id))
    }
    
    // Watcher saga, will invoke worker saga above upon action 'SHOW_NOTIFICATION_WITH_TIMEOUT'
    function* notificationSaga () {
      yield takeEvery('SHOW_NOTIFICATION_WITH_TIMEOUT', showNotificationWithTimeout)
    }
    
    export default notificationSaga
    

    Sagas are based on ES6 Generators

    // index.js
    
    import createSagaMiddleware from 'redux-saga'
    import saga from './sagas'
    
    const sagaMiddleware = createSagaMiddleware()
    
    const store = createStore(
      reducer,
      applyMiddleware(sagaMiddleware)
    )
    
    sagaMiddleware.run(saga)
    

    Compared to Redux Thunk

    Pros

    • You don't end up in callback hell.
    • You can test your asynchronous flows easily.
    • Your actions stay pure.

    Cons

    • It depends on ES6 Generators which is relatively new.

    Please refer to the runnable project if the code snippets above don't answer all of your questions.

提交回复
热议问题