Sending multiple actions with useReducers dispatch function?
Asked Answered
S

1

9

Is it possible to send multiple actions with a dispatch function when using the useReducer hook in react? I tried passing an array of actions to it, but that raises an unhandled runtime exception.

To be explicit, normally one would have an initial state object and a reducer like so:

const initialState = { message1: null, message2: null }

const messageReducer = (state, action) => {
  switch(action.type) {
    case SET_MESSAGE1:
      return {...state, message1: action.payload.message1}
    case SET_MESSAGE2:
      return {...state, message2: action.payload.message2}
    default:
      throw new Error("Something went wrong!")
  }
}

And then one could handle the state in the react applications using useReducers dispatch function like so.

[state, dispatch] = useReducer(messageReducer, initialState)
...
dispatch({type: SET_MESSAGE1: payload: {message1: "setting message1"})
dispatch({type: SET_MESSAGE2: payload: {message2: "setting message2"})

What I'd like to do is to send those two mutations in an array, so that I only need to invoke dispatch once, like so:

dispatch([
  {type: SET_MESSAGE1: payload: {message1: "setting message1"},
  {type: SET_MESSAGE2: payload: {message2: "setting message2"}
])

Now that I wrote this down, I realised that I could technically just write the reducer to accept an array instead of a string, and then map over that array. But is that considered a good practice?

Solatium answered 24/5, 2020 at 4:49 Comment(1)
On a side note, react will batch update the multiple dispatch call in the same function to improve performance. Exceptions are SetTimeOut, API calls etc.Nieberg
W
15

If you want to use dispatch only once:

You can add one more switch case SET_MULTIPLE into reducer :

const messageReducer = (state, action) => {
  switch(action.type) {
    case SET_MESSAGE1:
      return {...state, message1: action.payload.message1}
    case SET_MESSAGE2:
      return {...state, message2: action.payload.message2}
    case SET_MULTIPLE:
      return {...state, ...action.payload } // <---- HERE
    default:
      throw new Error("Something went wrong!")
  }
}

And change dispatch something like this :

dispatch({type: SET_MULTIPLE , payload: {message1: "setting message1" , message2 : "setting message2"})
Watchman answered 24/5, 2020 at 5:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.