Search code examples
reactjstypescriptreduxreact-redux

Typed dispatch with React-Redux


After the official tutorial I don't really understand how to properly dispatch an update with [email protected].

My setup looks like this:

export const mySlice = createSlice({
  name: 'MyItem',
  initialState: { field1: 'hello, world', field2: 0 },
  reducers: {
    setField: (state: { field1: string; field2: number }, action: PayloadAction<string>) => {
      state.field1 = action.payload;
    },
  },
});

export const store = configureStore({
  reducer: {
    myItem: mySlice.reducer,
  },
});

export type AppDispatch = typeof store.dispatch;

Inside of a component, I'm struggling with the dispatch:

const dispatch: AppDispatch = useDispatch();

// Resembles the `dispatch(increment())}` from the offical example, but I get a type error and I can't pass my update data.
// Additionally, the signature looks wrong (it looks like a reducer)
dispatch(mySlice.actions.setField());
// Since the signature doesn't match, TypeScript complains with `Void function return value is used`
dispatch(mySlice.actions.setField('newValue')) 
// TypeScript won't complain, but it doesn't seem like I could pass my update this way
dispatch(mySlice.actions.setField);
// TypeScript won't complain, but it's neither typed nor the recommended approach anyway
dispatch({ type: 'Idontexist', someValue: "hey" });

Thanks for your help!

Edit: The solution seems to be to use deconstructioning pattern:

export const {setField} = mySlice.actions;
...
dispatch(setField('newValue'))

But I've no clue why that's working while accessing dispatch(mySlice.actions.setField('newValue')) directly doesn't.


Solution

  • Export it correctly

    export const {setField} = mySlice.actions;
    

    now you can import it and dispatch(setField())