DEV Community

Abhirup Datta
Abhirup Datta

Posted on

Adding slices, reducer,actions and finishing up!

Our slice to handle our fruits state will be:

import {createSlice} from '@reduxjs/toolkit';

const initialState = {fruits: []};

const fruitsSlice = createSlice({
    name: 'fruits',
    initialState,
    reducers:{
        addFruit(state, action){
            console.log(action);
            state.fruits = [...state.fruits, action.payload];
        }
    }
});

export const {addFruit} = fruitsSlice.actions;
export default fruitsSlice;
Enter fullscreen mode Exit fullscreen mode

We can dispatch an action to update the addFruits reducer by calling it with the same name action.

const addFruitHandler = ()=>{
   setError(null);
   if(fruitName.length > 0 && Number.isInteger(fruitCount) && fruitCount > 0){
            console.log(fruitName, fruitCount);
            dispatch(addFruit({fruitName, fruitCount}));  //dispatching action
   }
   ......
}
Enter fullscreen mode Exit fullscreen mode

Lets breakdown what happening,

  • Our fruits slice is created from createSlice function provided by the RTK library.
  • createSlice accepts an object with three mandatory properties: name, initialState, reducers.

    • name is used when dispatching an action.(more on this later).
    • initialState is the initial state that this reducer will have.In our example, I have given an initial state.

    const initialState = {fruits: []}

    Note: Use null if we want to set initialState as empty.

    • reducers is an object containing Redux "case reducer" functions.It will have one or more actions depending on our application requirement.Here,I am creating one action addFruit to add a fruit object to our existing fruit list.
  • Finally, we are exporting the actions of this slice and the fruitSlice.

We will now link the reducer from fruitsSlice in our store.

Store reducer add

We can architect our code better by extracting out the actions in its own file.
Create a folder actions in our src folder and add a new file fruits.js inside it.

Fruit actions.

Let us take a deep look at the name of the slice and dispatch code inside AddFruit.js

dispatch(addFruit({fruitName, fruitCount}));
Enter fullscreen mode Exit fullscreen mode

Here, we are dispatching an object with fruitName and fruitCount.
By default, the action object of addFruit reducer will be
{type: "fruits/addFruit", payload: {fruitName: 'peach', fruitCount: 1}
.
Type is formed by <slice name>/<action name>
and payload is the parameter we pass in the dispatch function.

There is a bit of issue in the way we are dispatching our fruit name and count.
We have to make sure other components also dispatch with same object structure({fruitName:'',fruitCount:''}) which is a bad practice.
For that we create a custom payload by modifying our slice action,

const fruitsSlice = createSlice({
    ....
    reducers:{
        addFruit:{
            reducer: (state, action)=>{
                state.fruitList = [...state.fruitList, action.payload];
            },
            prepare: (name, count)=>{
                return {payload: {name, count}};
            }
        }
    }
});
Enter fullscreen mode Exit fullscreen mode

and our dispatch will now simply be

dispatch(addFruit(fruitName, fruitCount));
Enter fullscreen mode Exit fullscreen mode

The prepare method can accept any paramaters and returns a custom payload.

Now, we will be consuming the fruit list from our fruits state in FruitList component.

Fruit list

That's it!


The final application can be found here:

https://github.com/abhidatta0/fruits-logger-redux-toolkit

The complete code can be found here:

https://github.com/abhidatta0/fruits-logger-redux-toolkit

Top comments (0)