DEV Community

Atilla Baspinar
Atilla Baspinar

Posted on

11 - React: Redux and Redux Toolkit (RTK)

Redux is a state management library used when application state becomes large or shared across many components.

The main idea is:

  • state lives in a central store
  • components read state through selectors
  • components update state by dispatching actions
  • reducers decide how the state changes

1) Redux basics

A reducer is a function that receives the current state and an action, then returns the next state.

const initialState = { counter: 0 };

const reducer = (prevState = initialState, action: { type: string; payload?: number }) => {
  if (action.type === 'inc') {
    return {
      ...prevState,
      counter: prevState.counter + (action.payload ?? 1),
    };
  }

  return prevState;
};
Enter fullscreen mode Exit fullscreen mode

Important rule:

  • never mutate the existing state object
  • always return a new object
  • keep all existing keys in the returned object unless you intentionally want to remove them

Creating the store

import { createStore } from 'redux';

const store = createStore(reducer);
Enter fullscreen mode Exit fullscreen mode

Providing the store to React

import { Provider } from 'react-redux';

<Provider store={store}>
  <App />
</Provider>
Enter fullscreen mode Exit fullscreen mode

Reading and updating state in a component

import { useDispatch, useSelector } from 'react-redux';

function Counter() {
  const counter = useSelector((state: { counter: number }) => state.counter);
  const dispatch = useDispatch();

  const increment = () => {
    dispatch({ type: 'inc', payload: 5 });
  };

  return (
    <>
      <p>Counter: {counter}</p>
      <button onClick={increment}>+5</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

useSelector reads data from the Redux store.
useDispatch sends an action to the reducer.

2) Redux Toolkit

Redux Toolkit is a simpler and more structured way to write Redux.

It gives us:

  • createSlice
  • configureStore
  • simplified reducer logic
  • automatic action creators

Example: counter slice

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

const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    counter: 0,
    show: false,
  },
  reducers: {
    increment(state) {
      state.counter += 1;
    },
    increase(state, action) {
      state.counter += action.payload;
    },
  },
});
Enter fullscreen mode Exit fullscreen mode

In Redux Toolkit, the reducer functions are written in a simpler style. We do not need a large switch statement, and we do not manually return the whole state object every time.

The state is still updated immutably under the hood by Immer, which is why we can mutate the draft state directly.

Configure the store

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

const store = configureStore({
  reducer: {
    counterReducer: counterSlice.reducer,
  },
});
Enter fullscreen mode Exit fullscreen mode

Export actions

export const counterActions = counterSlice.actions;
Enter fullscreen mode Exit fullscreen mode

Use it in a component

import { useDispatch, useSelector } from 'react-redux';
import { counterActions } from './store';

function Counter() {
  const counter = useSelector((state: any) => state.counterReducer.counter);
  const dispatch = useDispatch();

  return (
    <>
      <p>Counter: {counter}</p>
      <button onClick={() => dispatch(counterActions.increment())}>+</button>
      <button onClick={() => dispatch(counterActions.increase(5))}>+5</button>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

counterActions.increment() creates an action for the reducer, and counterActions.increase(5) sends a payload value.

3) Why Redux Toolkit is preferred

Redux Toolkit reduces boilerplate and makes Redux easier to work with.

It helps with:

  • fewer manual action types
  • less reducer boilerplate
  • simpler state updates
  • better organization for growing apps

4) Summary

  • Redux stores data in one central store
  • reducers handle state changes using actions
  • useSelector reads state from the store
  • useDispatch sends actions to update state
  • Redux Toolkit is the modern and easier way to use Redux

In practice, Redux Toolkit is usually the recommended choice for Redux-based apps because it keeps the same concepts but with much less code.

Top comments (0)