Skip to content

Redux Toolkit: How to easily create Redux store with reducers

Redux Toolkit: How to easily create Redux store with reducers

Redux Toolkit is a library that provides a set of utilities and best practices for writing Redux logic. It was created to simplify the process of creating and maintaining Redux code, by reducing the amount of boilerplate code needed and providing a standardized way of handling common use cases.

Redux Toolkit

Some of the features provided by Redux Toolkit include:

  1. A configureStore() function that automatically sets up a Redux store with sensible defaults, including the ability to use middleware and configure the devtools extension.
  2. A createSlice() function that generates Redux “slice” reducer functions, which are simpler and more modular than traditional Redux reducers. Slices include automatic creation of action creators and action types.
  3. A createAsyncThunk() function that generates async action creators that automatically dispatch pending, fulfilled, and rejected actions based on the promise state.
  4. A createEntityAdapter() function that generates an adapter for managing collections of entities in the store, including automatically generating reducer functions for common CRUD operations.
  5. A createSelector function that simplifies creating memoized selectors that compute derived state.
  6. An immer integration that allows you to write Redux reducers that modify state directly, without requiring you to write immutable update logic.
  7. A batch function that allows you to batch multiple Redux actions together into a single batch, reducing the number of renders in React applications.

These features, along with others, make Redux Toolkit a powerful tool for building complex Redux applications. Additionally, the toolkit has gained widespread adoption in the Redux community, and its usage is recommended in the official Redux documentation.

Example of how Redux Toolkit can simplify the process of creating a Redux store and writing reducers.

First, let’s create a Redux store using the configureStore() function:

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});

In this example, we import the configureStore() function from Redux Toolkit and use it to create a store with a single reducer, counterReducer, which we’ll define next.

Next, let’s define a reducer using the createSlice() function:

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

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    reset: (state) => {
      state.value = 0;
    },
  },
});

export const { increment, decrement, reset } = counterSlice.actions;

export default counterSlice.reducer;

In this example, we import the createSlice() function from Redux Toolkit and use it to define a slice reducer for managing a simple counter state. The createSlice() function automatically generates action types and action creators for each reducer function defined in the reducers object.

Finally, we export the action creators and the reducer function from the module, which we can then use in our React components to update and display the counter state:

import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, reset } from './counterSlice';

function Counter() {
  const value = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <div>{value}</div>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
      <button onClick={() => dispatch(reset())}>Reset</button>
    </div>
  );
}

In this example, we use the useSelector() and useDispatch() hooks from the react-redux library to read and update the counter state in our React component. We dispatch the increment(), decrement(), and reset() actions using the action creators generated by the createSlice() function, which automatically generate the correct action types and payloads for us.

When we dispatch these actions, the Redux store will automatically update the counter state using the reducer function generated by createSlice(). The reducer function modifies the state directly using the immer library, which allows us to write simpler and more concise reducer logic without worrying about immutability.

Conclusion

Overall, this example demonstrates how Redux Toolkit can simplify the process of creating and managing Redux state in a React application. The configureStore() and createSlice() functions help reduce the amount of boilerplate code needed to set up a Redux store and write reducers, while the useSelector() and useDispatch() hooks provide a simple and intuitive way to read and update state in our React components.

Further Reading

Redux vs MobX: Which is better state management library

Please share