Search code examples
typescriptreduxredux-toolkit

Redux Toolkit "action.payload" query


const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    // User k set korche
    setUser: (state, action: PayloadAction<string | null>) => {
      state.user.email = action.payload;
    },
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.isLoading = action.payload;
    },
  },
});

I want to clear the concept of action.payload. Why I use it here and what does it do.


Solution

  • Given the Redux-Toolkit (RTK) slice:

    const userSlice = createSlice({
      name: 'user',
      initialState,
      reducers: {
        // User k set korche
        setUser: (state, action: PayloadAction<string | null>) => {
          state.user.email = action.payload;
        },
        setLoading: (state, action: PayloadAction<boolean>) => {
          state.isLoading = action.payload;
        },
      },
    });
    

    and assumed exports:

    export const { setUser, setLoading } = userSlice.actions;
    export default userSlice.reducer;
    

    This slice generates a few things, but most notably it generates the exports above:

    1. Generates setUser and setLoading action functions based on the reducer functions you have declared.
    2. A slice reducer function that is passed to the store, or combined with other reducers to form a reducer tree, when the store object is created. e.g. configureStore.

    I want to clear the concept of action.payload. Why I use it here and what does it do?

    All Redux action functions return an action object, e.g. an object with a type property. RTK-generated actions return action objects with a payload property. This is the action.payload you see in the reducer functions.

    If for example you dispatch the setUser action from the UI.

    dispatch(setUser("Drew"));
    
    dispatch(setUser(null));
    

    This first calls the setUser action with the string argument "Drew"|null, and returns an action object { type: "user/setUser", payload: "Drew" }|{ type: "user/setUser", payload: null } that is passed to the dispatch function, similar to dispatch({ type: "user/setUser", payload: "Drew" }), to be passed to the reducer tree.

    The setReducer reducer function then handles this "user/setUser" action type and accesses the action object's payload property.

    setUser: (state, action: PayloadAction<string | null>) => {
      state.user.email = action.payload; // "Drew" or null
    }
    

    The result is that state.user.email is set to the payload value "Drew" in the store.

    Similarly you can dispatch a boolean value with the setLoading action.

    dispatch(setLoading(true));
    
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.isLoading = action.payload; // true
    },