Understanding Redux: A Comprehensive Tutorial with Examples

4 mn read

Introduction to Redux

In the ever-evolving world of web development, new JavaScript libraries are constantly emerging. However, chasing after each new release without fully understanding their benefits isn’t advisable. One such library that has stood the test of time is Redux. In this guide, we’ll provide a foundational understanding of Redux, highlighting its functionalities and why you should use it. We’ll explore its benefits using a simple but practical component.

An Introduction to Redux

Redux is a predictable state container designed to help you write JavaScript apps that behave consistently across client, server, and native environments, and are easy to test. While it’s mostly used as a state management tool with React, you can use Redux with any other JavaScript framework or library. It’s lightweight at 2KB (including dependencies), so you don’t have to worry about it making your application’s asset size bigger.

With Redux, the state of your application is kept in a store and each component can access any state that it needs from this store.

When to Use Redux

Redux allows you to manage your app’s state in a single place and keep changes in your app more predictable and traceable, making it easier to understand the changes happening in your app. However, Redux introduces some boilerplate code, which some developers find unnecessary. Whether you need Redux usually becomes apparent as your app grows and managing state becomes more complex.

What is Redux Used For?

Redux is used to maintain and update data across your applications for multiple components to share, all while remaining independent of the components. It shines in large applications where state management becomes challenging.

Using Redux with React

Redux is a standalone library that can be used with various JavaScript frameworks including Angular, Inferno, Vue, Preact, and React. However, Redux is most frequently used with React. This is because React allows for a uni-directional flow of data, which works well with Redux’s state management model.

State Management with Redux

State management is essentially a way to facilitate the communication and sharing of data across components. In React, this often means lifting state up to the nearest common ancestor component and passing it down as props. Redux simplifies this by keeping the state in a single store, making it easier to manage and debug.

Here’s a simple example of a login component in React:

import React, { useState } from 'react';

const App = () => {
  const [count, setCount] = useState(0);

  const handleIncrement = (incrementBy) => {
    const numberToIncrement = incrementBy || 1;
    setCount(count + numberToIncrement);
  }

  return (
    <div>
      <BigCountDisplay count={count} />
      <CounterButton onIncrement={handleIncrement} />
    </div>
  );
}

export default App;

In this example, state is managed within the component. As your app grows, this can become cumbersome. Redux helps by managing state in a single store.

How Redux Works

Redux operates with three core concepts: actions, reducers, and store.

Redux Actions

Actions are the only way to send data from your application to your Redux store. They are plain JavaScript objects that must have a type property indicating the type of action to be carried out.

Example of an action:

{ 
  type: "INCREMENT",
  payload: {
    incrementBy: 5
  }
}

Action creator function:

const getIncrementAction = (numberToIncrement) => {
  return {
    type: "INCREMENT",
    payload: {
      incrementBy: numberToIncrement
    }
  }
}

Redux Reducers

Reducers are pure functions that take the current state of an application, perform an action, and return a new state. They handle how the state will change in response to an action.

Example of a reducer:

const CounterReducer = (state = initialState, action) => {
  switch (action.type) {
    case "INCREMENT":
      return state + (action.payload.incrementBy || 1);
    default:
      return state;
  }
};

Redux Store

The store is a container that holds the application state. The only way to change the state is by dispatching actions to the store. It allows components to subscribe to state changes and update accordingly.

Redux Toolkit

Redux Toolkit simplifies the process of setting up and using Redux by providing utilities to handle common tasks. It reduces boilerplate and improves readability.

Example of setting up a store with Redux Toolkit:

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

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

export default store;

Creating an action using Redux Toolkit:

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

const addTodo = createAction('INCREMENT');
addTodo({ val: 5 }); // {type: "INCREMENT", payload: {val: 5}}

Creating a reducer with Redux Toolkit:

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

const increment = createAction('counter/increment');
const incrementByAmount = createAction('counter/incrementByAmount');

const initialState = { value: 0 };

const counterReducer = createReducer(initialState, (builder) => {
  builder
    .addCase(increment, (state) => {
      state.value++;
    })
    .addCase(incrementByAmount, (state, action) => {
      state.value += action.payload;
    });
});

Redux Middleware

Middleware allows you to intercept actions before they reach the reducer. They can perform tasks such as logging, crash reporting, and handling asynchronous actions.

Example of simple middleware:

function simpleMiddleware({ getState, dispatch }) {
  return function(next) {
    return function(action) {
      const nextAction = next(action);
      const state = getState();
      return nextAction;  
    }
  }
}

Benefits of Using Redux

  • Predictable State: Redux makes the state predictable by enforcing immutability and pure functions.
  • Maintainability: Redux’s strict organization makes it easier to maintain large applications.
  • Ease of Debugging: Redux’s logging and DevTools make it easy to debug applications.
  • Performance: Redux optimizes performance by re-rendering only when necessary.
  • Ease of Testing: Pure functions in Redux are easy to test.
  • State Persistence: Redux can persist state to localStorage and restore it after a refresh.
  • Server-Side Rendering: Redux supports server-side rendering, enhancing initial load performance.

Conclusion

Redux is a powerful tool for state management in JavaScript applications, especially as they grow in complexity. While it introduces some boilerplate, the benefits in terms of maintainability, predictability, and ease of debugging are significant. However, it’s important to evaluate whether your project truly needs Redux before integrating it.


Feel free to share your thoughts and questions in the comments below. Happy coding!


Leave a Reply

Your email address will not be published. Required fields are marked *

Reading is essential for those who seek to rise above the ordinary.

ABOUT US

The internet as we know is powerful. Its underlying technologies are transformative, but also, there’s a plethora of haphazard information out there.We are here to serve you as a reliable and credible source to gain consistent information

© 2024, cloudiafrica
Cloudi Africa