Redux Toolkit generate and return an id (return data from action)

Viewed 973

I'm trying to create an object and add it to a reducer, but have the action/reducer take care of generating the id.

Per this answer, it seems the accepted pattern is to generate the id in the action creator:

const todosSlice = createSlice({
  name: "todos",
  initialState: [],
  reducers: {
    addTodo: {
      reducer(state, action) {
        state.push(action.payload);
      },
      prepare(text) {
        const id = uuid();
        return { payload: {text, id} };
      }
    }
  }
})

However, suppose I want to then use / refer to the id after creating the todo, something like

dispatch(addTodo('Say hello world')) // creates a todo with a uuid
...
id = <some way to get the id>
doSomethingElseWithTodoGivenId()

Does Redux-Toolkit provide any assistance with achieving this? I looked at createAsyncThunk, but that appears to be more focussed around async data fetching status.

I know I can do this with redux-thunk (by awaiting the dispatch and having the thunk action generate the id):

const id = await dispatch(createTodoWithGeneratedId('Say hello world'))

or by having the caller generate the id. But I'm wondering if there's a better way.

1 Answers

Unfourtonately, dispatch is not working that way. Plain Redux dispatch call retuns a dispatched action, but redux-toolkit using thunk middleware by default that changes a dispatch returning value to promise that fullfiled with dispatched action. You can't get a result of dispatching result from dispatch call itself, it is impossible and conflicts with it's nature.

However, you can create a thunk that dispatches different actions based on promise result. Check official documentation about creating thunk with side effects. For more advanced usage check this answer in SO.

If you are using redux-toolkit, you can use createAsyncThunk, it is implements the same logic but without much more boilerplate code.

Related