Skip to main content

Redux Toolkit

Redux is a predictable state container for JavaScript apps. Redux Toolkit is the official, opinionated, batteries-included toolset for efficient Redux development.

It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
Refer to official Redux documentation for detailed usage. β†’
Refer to official Redux Toolkit documentation for detailed usage. β†’

superplate serves an optional redux plugin that uses @reduxjs/toolkit

Configure Store & Setup Reducers and Slices#

  • Create a store with a root reducer

Refer to official documentation on configuring store for detailed usage. β†’

src/redux/store.ts
import { configureStore } from "@reduxjs/toolkit";
import rootReducer from "./reducers";
export default configureStore({ reducer: rootReducer });
  • Add a root reducer that combines reducers.

Refer to official documentation on combineReducers for detailed usage. β†’

src/redux/reducers.ts
import { combineReducers } from "redux";
import counter from "@redux/slices/counter";
export default combineReducers({ counter });

createSlice accepts an initial state, an object full of reducer functions, and a "slice name", and automatically generates action creators and action types that correspond to the reducers and state.

src/redux/slices/counter/index.ts
import { createSlice } from "@reduxjs/toolkit";
const initialState = {    count: 20,};
const counterSlice = createSlice({    name: "counter",    initialState,    reducers: {        increase: (state) => {            state.count++;        },        decrease: (state) => {            state.count--;        },    },});
export const { increase, decrease } = counterSlice.actions;
export default counterSlice.reducer;
info

Since Redux Toolkit uses Immer under the hood, you can use mutating immutable updates.

increase(state) {    state.value++},
  • Pass store to Provider from React-Redux in _app.tsx
pages/_app.tsx
import React from "react";import { AppProps } from "next/app";import { Provider } from "react-redux";
import store from "@redux/store";
function MyApp({ Component, pageProps }: AppProps): JSX.Element {  return (    <Provider store={store}>      <Component {...pageProps} />    </Provider>  );}
export default MyApp;

Now everything's ready to read data from store and dispatch some actions to make changes to store state.

tip

All this work will be handled automatically by CLI, so you don’t need to do anything extra as long as you choose Redux Toolkit plugin during the project creation phase.

Hooks (useSelector & useDispatch)#

useSelector from React-Redux is used to read data from store. It accepts a single selector function. A selector is a function that takes the entire Redux store state as its argument, reads some value from the state, and returns that result.

The React-Redux also provides a useDispatch hook that gives us the store's dispatch method as its result. This method is used to dispatch actions to make changes to the store state.

src/components/counter/index.tsx
import React from "react";import { useDispatch, useSelector } from "react-redux";
import { increase, decrease } from "@redux/actions";import { IState } from "@redux/istate";
export default function Counter() {  const dispatch = useDispatch();  const count = useSelector((state: IState) => state.counter.count);    return (    <div>      <div>        <h2>Counter</h2>        <button          type="button"          onClick={() => dispatch(increase())}        >          +        </button>        <span>{count}</span>        <button          type="button"          onClick={() => dispatch(decrease())}        >          -        </button>      </div>    </div>  );}

Refer to official documentation on Hooks usage for detailed usage. β†’

increase and decrease are action creator methods that return actual action objects for dispatch. They are generated by createSlice and can be accessed from the slice. createSlice uses createAction under the hood to produce action creators.
Refer to official documentation on createAction usage for detailed usage. β†’

src/redux/slices/counter/index.ts
...
export const { increase, decrease } = counterSlice.actions;
src/redux/actions.ts
export { increase, decrease } from "@redux/slices/counter";

Middleware#

Redux middleware provides a third-party extension point between dispatching an action, and the moment it reaches the reducer. Redux middleware can be used for logging, crash reporting, talking to an asynchronous API, routing, and more.

Refer to official documentation on Redux Middleware for detailed usage. β†’
Refer to official documentation on Redux Toolkit Middleware for detailed usage. β†’

RTK Query#

Refer to official documentation on RTK Query for detailed usage. β†’

Adding Redux Toolkit to your project later#

If you didn't choose the plugin during project creation phase, you can follow the instructions below to add it.

  • Install @reduxjs/toolkit and react-redux packages
npm install @reduxjs/toolkit react-redux

Refer to official documentation on installation for detailed usage. β†’