Redux Toolkit With React

Introduction:

Redux Toolkit is a global state management library that makes it easier for developers to handle and organize the application's data by providing helpful tools and clear rules, simplifying the process of managing the state.

What is Global state management?

  • Global state management is like having a central hub for the data, making it easy to access and update the data across the components.

Why do we need Global state management?

  1. State Sharing Across Components

  2. Single Source of Truth

  3. Avoidance of Prop Drilling

Installing Redux Toolkit:

  • npm install @reduxjs/toolkit - For installing the Redux Toolkit package.

  • npm install react-redux - This package will help us to connect redux with react

Use yarn add instead of npm install if you prefer yarn

File Structure:

/src
|-- App.js
|-- features
|   |-- counter
|       |-- CounterComponent.js
|       |-- counterSlice.js
|
|-- store
|   |-- store.js
|
|-- index.js

I usually organize my Redux related files in the 'features' folder with the structure described above.

Boilerplate:

// store/store.js
import { configureStore } from '@reduxjs/toolkit';

export const store = configureStore({
    reducer: {},
});
  • configureStore is a function provided by the Redux Toolkit library that helps us create the store.

  • The reducer is where you list the reducers that handle different parts of your app's data.

// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
    // Some initial values
};
const counterSlice = createSlice({
  name: 'counter', // name of the slice
  initialState,   // Initial state for the slice
  reducers: {},
});
  • createSlice function from Redux Toolkit. That helps create Redux slices, which include the reducer functions and actions related to a specific part of the state.

  • reducers field is where you will define the functions that handle state changes for the feature.

Connect Redux Store to React:

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/App';
import { Provider } from 'react-redux';
import { store } from './store/store';

ReactDOM.render(
  <Provider store={store}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Provider>,
  document.getElementById('root')
);
  • <Provider store={store}> Wraps your entire React application with the Provider component and passes the store as a prop. This ensures that the Redux store is available to all components in the application.

Creating Reducers:

// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  value: 0,
};

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

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
  • Reducers define functions inside the reducers object. In this case, we have increment and decrement reducers. When using Redux, we avoid mutable logic, but Redux Toolkit (RTK) uses a package called Immer, which automatically converts our mutable logic into immutable logic.

  • The increment reducer takes the current state (state) and an action (action). It increments the value property by the payload provided in the action.

  • The decrement reducer takes the current state (state) and an action (action). It decrements the value property by the payload provided in the action.

  • Both the state and action are automatically handled by RTK (Redux Toolkit).

  • Exports action functions (increment and decrement) that can be used in components to dispatch actions. Also, export the counterSlice.reducer itself for managing the state in Redux.

Redux Store Configuration:

// store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';

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

export default store;
  • Import the counterReducer from the location where it's defined. This assumes you have a Redux slice named counterSlice in the features/counter directory.

Using in React:

// features/counter/CounterComponent.js
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

const CounterComponent = () => {
  const counterValue = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <p>Counter Value: {counterValue}</p>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
};

Importing Hooks and Actions:

  • import { useSelector, useDispatch } from 'react-redux';: Import the useSelector and useDispatch hooks from react-redux. These hooks allow the component to interact with the Redux store.

  • import { increment, decrement } from './counterSlice';: Import the increment and decrement action functions from counterSlice. These actions are used to dispatch changes to the Redux store.

Using Redux Hooks and Actions:

  • const counterValue = useSelector((state) => state.counter.value);: Utilize the useSelector hook to retrieve the counter.value from the Redux store. This value represents the current count managed by Redux.

  • const dispatch = useDispatch();: Employ the useDispatch hook to obtain the dispatch function, enabling the component to dispatch actions to the Redux store."

Conclusion:

  • Simplified State Management: Redux Toolkit streamlines state management in React applications.

  • Clear Structure: The toolkit provides a clear structure, enhancing code organization and readability.