BOSC
How To Dispatch A Redux Action With A Timeout

React: How To Dispatch A Redux Action With A Timeout?

Do you want to dispatch a redux action with a timeout? If yes, then this onsite blog can give you a better chance to make it possible. Generally, you should never get into the trap of thinking that a library can prescribe you everything.

If you are new to this topic, don’t worry! we have uploaded a beginner’s friendly guide on redux. Check this out.

When you want to do something with the JavaScript timeout, then sure you have to use setTimeout. Here there is no special reason why redux actions are different from others. When you want to dispatch a redux action with a timeout, you can get help from React professionals and acquire React js development services for your projects.

Redux can provide the most effective alternative ways to deal with the asynchronous stuff. But you have to use them after realising that you are repeating the code too much. When you are facing this problem, then you have to use what your entire language offers. Finally, you can get the simplest solution.

Writing Async Code Inline

It is the simplest process and there is nothing specific to the redux here
store.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
store.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)
Similarly, from around the connected component:
this.props.dispatch({ type: 'SHOW_NOTIFICATION', text: 'You logged in.' })
setTimeout(() => {
this.props.dispatch({ type: 'HIDE_NOTIFICATION' })
}, 5000)

The major difference is that, here in this connected component, you don’t need to access the store itself. But either you can get dispatch() or particular action creators that are injected as props. You will never get any difference from here.

When you don’t like making types while dispatching the same actions from various components, then you have to extract the action creators. Instead, you can dispatch the action objects to inline effectively:

// actions.js
export function showNotification(text) {
return { type: 'SHOW_NOTIFICATION', text }
}
export function hideNotification() {
return { type: 'HIDE_NOTIFICATION' }
}

// component.js
import { showNotification, hideNotification } from '../actions'
this.props.dispatch(showNotification('You just logged in.'))
setTimeout(() => {
this.props.dispatch(hideNotification())
}, 5000)

Or, in case you have bound them previously with connect():

this.props.showNotification('You just logged in.')
setTimeout(() => {
this.props.hideNotification()
}, 5000)

Till now there is no middleware or other advanced concept that has been used.

Extraction of Async Action Creator:

  • Even the above-mentioned approach is very simple, but you may face some serious problems:
  • It may force you to duplicate the logic anywhere you want for showing the notification.

Such notifications will never have any IDs. Therefore there you will have the race condition when you show two essential notifications very fast. If the first time out is completed, then it will dispatch the HIDE_NOTIFICATION. Along with that, it will hide the second notification very fast after the timeout.

For solving these problems, you have to extract the function that integrates the timeout logic and dispatch major actions. It may look like this:

// actions.js
functionshowNotification(id, text) {
return { type: 'SHOW_NOTIFICATION', id, text }
}
functionhideNotification(id) {
return { type: 'HIDE_NOTIFICATION', id }
}

letnextNotificationId = 0
export function showNotificationWithTimeout(dispatch, text) {
  // Assigning IDs to notifications lets reducer ignore HIDE_NOTIFICATION
  // for the notification that is not currently visible.
  // Alternatively, we could store the timeout ID and call
  // clearTimeout(), but we’d still want to do it in a single place.
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
  }, 5000)
}

During this time, components make use of showNotificationWithTimeout without duplicating any logic or having race conditions with various notifications:

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

// otherComponent.js
showNotificationWithTimeout(this.props.dispatch, 'You just logged out.')    

 

Now showNotificationWithTimeout() needs to accept the dispatch as the first argument. It is mainly since; it must have to dispatch the actions to the store. A component is able to access dispatch but an external function is needed to take complete control over dispatching. Finally, it is best to give control over the dispatching.

When you are having the singleton store exported from a certain module, then instead you have to import it and then directly dispatch:

// store.js
export default createStore(reducer)

// actions.js
import store from './store'
// ...

letnextNotificationId = 0
export function showNotificationWithTimeout(text) {
const id = nextNotificationId++
store.dispatch(showNotification(id, text))
setTimeout(() => {
store.dispatch(hideNotification(id))
  }, 5000)
}

// component.js

showNotificationWithTimeout('You just logged in.')

// otherComponent.js

showNotificationWithTimeout('You just logged out.')    

It will force the store to be the singleton. It can become very hard to implement the server rendering.

You must need each request to access its own store on the server.

Therefore different users can get different preloaded data. Here a singleton store can make the testing process very hard. You were never able to mock the store anymore while testing the action creators. It is because; they refer to a certain real store that is exported from a certain module. You could never reset that state from outside.

Therefore when you technically are able to export the singleton store from the module, then experts strictly oppose it. You should never do it unless you ensure that your app won’t add any server rendering.

Now you have to get back to the previous version:

<// actions.js
// ...

letnextNotificationId = 0
export function showNotificationWithTimeout(dispatch, text) {
const id = nextNotificationId++
dispatch(showNotification(id, text))
setTimeout(() => {
dispatch(hideNotification(id))
  }, 5000)
}

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

// otherComponent.js
showNotificationWithTimeout(this.props.dispatch, 'You just logged out.')    

It can solve certain problems with logic duplication and save a lot from race conditions.

Thunk middleware:

The approach should be sufficient for simple apps. When you are happy, then don’t worry about the middleware. You may get certain inconveniences in larger apps.

Redux thunk can teach redux to explore special actions.

import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
const store = createStore(
reducer,
applyMiddleware(thunk)
)

// It still recognizes plain object actions
store.dispatch({ type: 'INCREMENT' })

// But with thunk middleware, it also recognizes functions
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)
})

Conclusion:

From the above-mentioned scenario, now you have found out the procedure to dispatch a redux action with a timeout. Therefore hire react js development services to dispatch a redux action with a timeout. Get help from a group of professional experts.

Stuck in your development problems or need professionals to resolve your problems? Hire Mobile App Development Agency for software development solutions.