3

In React with Redux, when there are some user operations, e.g., in facebook, user adds some comments, I will call dispatch() to send the add action to redux store, but when should I call back end API to save these data to database? do I need to do it together with dispatch()?

thanks

Benjamin Li
  • 1,687
  • 7
  • 19
  • 30
  • 1
    Yes, preferably. You might add comment to redux store immediately after form submit and send request to backend. If it's saved successfully you're good. If request fails for some reason, you might consider visual notice for user letting him know it failed - e.g "You are not connected to internet"... So, send request whenever needed and when it makes sense! :) no general rule here... – Andreyco Dec 29 '16 at 22:56

1 Answers1

1

One solution would be to transfer your API logic into a thunk using a middleware package such redux-thunk (or similar).

Using thunks allows you to treat special kinds of actions as functions which means you can extend a plain action with specific action-related logic. The example you give of needing to serialize your state is an excellent use-case for redux-thunk.

You should note that, unlike reducers, thunks explicitly support fetching state and dispatching subsequent actions via the getState and dispatch functions.

Below is an ES6 example of how such a multi-purpose thunk might look.

To demo the getState() method the new item will only be saved via the api only if the redux state shouldSave value is truthy.

I would also use the async/await syntax to make sure the the api call succeeds before dispatching the local redux action.

Thunk Example - adding a new item

import api from './api'

export const addNew = async (item) => {
  return (dispatch, getState) => {
    try{
      const state = getState()
      if(state.shouldSave){
        await api.save(item)
      }
      dispatch({
        type: ITEM_ADD_NEW,
        data: item
      })
    }catch(err){
      const error = new Error("There was a problem adding the new item")
      error.inner=err
      throw(error)
    }
  }
}
biofractal
  • 18,963
  • 12
  • 70
  • 116