Logo

dev-resources.site

for different kinds of informations.

Taming the State Beast: Redux vs. Recoil in React

Published at
1/31/2024
Categories
beginners
programming
react
state
Author
sawincp
Categories
4 categories in total
beginners
open
programming
open
react
open
state
open
Author
7 person written this
sawincp
open
Taming the State Beast: Redux vs. Recoil in React

React's beauty lies in its component-driven nature, but managing state across those components can become messy. That's where state management libraries like Redux and Recoil come in, wrangling your app's data into a smooth, predictable flow. But which one deserves a place in your toolkit? Let's break down their key differences:

Architecture

  1. Redux: Think of Redux as a central bank for your app's state. Everything goes in and out through a single source of truth, the store. Actions, sent by components, trigger reducers that update the store, and changes automatically ripple through the app.

  2. Recoil: Imagine a network of smaller vaults, called atoms, scattered across your components. They each hold independent pieces of state, connected by selectors that can combine or transform data between them. Updates happen locally, with only affected components notified.

Learning Curve

  1. Redux: Buckle up for a steeper climb. Redux has a well-defined structure and requires more boilerplate code, but its predictability and extensive community support make it a reliable choice for complex projects.

  2. Recoil: Take a gentler slope. Recoil boasts a simpler API and less code, making it easier to jump in. However, its decentralized nature can feel less structured and lacks the same level of community resources as its established counterpart.

How it works: Redux

At its core, Redux allows us to create a single source of truth for our application. Think of this as a vault which holds the entire application's state which is called a store.

To set up a store you have to set up a pure function called a Reducer that takes in the current state and an action that returns the updated state.

function counterReducer(state = 0, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}
Enter fullscreen mode Exit fullscreen mode

To store your initial values and you need to import the createStore function from the Redux library.

import { createStore } from 'redux';

const initialState = {
  counter: 0,
};
Enter fullscreen mode Exit fullscreen mode

From here you can create your store (vault) with your reducer and initial state as arguments...

const store = createStore(counterReducer, initialState);

This will create the store object that will hold your app's state and manage its updates.

How to use Store from Redux

In order to use your newly created store you first need to wrap your root component with the Provider component and pass the store as a prop. This allows the store to be accessible to all components in your app.

import React from 'react';
import { Provider } from 'react-redux';
import store from './store'; // Import your created store

function App() {
  return (
    <Provider store={store}>
      {/* Your app components here */}
    </Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode

From here we can connect two hooks to the store in our components.

1) Use the useSelector hook to read data from the store into your component.

2) Use the useDispatch hook to dispatch actions that trigger state updates in your components.

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

function CounterComponent() {
  const count = useSelector((state) => state.counter);
  const dispatch = useDispatch();

  const handleIncrement = () => {
    dispatch({ type: 'INCREMENT' });
  };

  return (
    <div>
      Count: {count}
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

In our example our useSelector retrieves the data from our Redux store by accessing the counter value and storing it in the count variable. It allows the component to display the current count and react to changes in the store.

useDispatch will dispatch our action to trigger state updates in the store. The useDispatch hook returns a function called dispatch that's used to send actions to the Redux store. When our handleIncrement function is called, it dispatches an action with the type "INCREMENT" to our Redux store where our Reducer receives that action and performs the necessary logic and stores the new state value in our counter variable.

PHEWWWWW.... that's a lot to take in. Let's take a look at our other example.

How it works: Recoil

One of the biggest differences between Recoil and Redux is how they approach state.

Redux uses a single store to hold the entire app's state where components read and update the store through actions and reducers (Centralized).

Recoil uses atoms scattered across components, each holding a specific piece of state where components can directly access and update these atoms (Decentralized).

To use Recoil we first have to import and define an atom from our Recoil library.

import { atom } from 'recoil';

const counterState = atom({
  key: 'counter',
  default: 0,
});
Enter fullscreen mode Exit fullscreen mode

Similar to Redux, we then have to make Recoil available throughout our app by wrapping our root component with RecoilRoot.

import React from 'react';
import { RecoilRoot } from 'recoil';

function App() {
  return (
    <RecoilRoot>
      {/* Your app components here */}
    </RecoilRoot>
  );
}
Enter fullscreen mode Exit fullscreen mode

From here we can use Recoil hooks just like our useState hooks from our React library. We use useRecoilState in our components to read and update our state in the component.

import { useRecoilState } from 'recoil';

function CounterComponent() {
  const [count, setCount] = useRecoilState(counterState);

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

  return (
    <div>
      Count: {count}
      <button onClick={handleIncrement}>Increment</button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Like our useState hook, when a user clicks on our button and triggers our handleIncrement function, the function process the request by updating the setState variable which directly updates the value of our counterState atom.

Seems a little bit easier eh?

Conclusion

Both of these state management libraries are powerful tools to help tame state in your application. While Redux has a predictable data flow and a centralized store, it also comes with a steeper learning curve and less flexible architecture. Recoil on the other hand provides a simple API with flexible and decentralized state management but is considered less mature with a smaller community than Redux.

Ultimately, the best choice for your project depends on your project needs and preferences:

Choose Redux if you have a large and complex application requiring predictable state management, strong community, and established best practices

OR

Choose Recoil if you prefer a simpler API, have smaller projects, and prioritize potential performance benefits.

Choose the tool that's right for you!

state Article's
30 articles in total
Favicon
Svelte 5: Share state between components (for Dummies)
Favicon
Pampanga State Agricultural University
Favicon
Data Flow in LLM Applications: Building Reliable Context Management Systems
Favicon
Props and State in React
Favicon
Radar Market Innovations: Phased Array Solid-State Radar Development
Favicon
A single state for Loading/Success/Error in NgRx
Favicon
Advanced State Management - XState
Favicon
Top 7 Tips for Managing State in JavaScript Applications 🌟
Favicon
MithrilJS component with state management
Favicon
React State Management: When & Where add your states?
Favicon
STATE MANAGEMENT IN REACT
Favicon
State Management with Zustand
Favicon
A practical summary of React State variables & Props!
Favicon
State in React
Favicon
Weak memoization in Javascript
Favicon
Crafting a Global State Hook in React
Favicon
Reusing state management: HOC vs Hook
Favicon
State Vs Prop in React [Tabular Difference]
Favicon
Mastering XState Fundamentals: A React-powered Guide
Favicon
Does limiting state matter on the FrontEnd?
Favicon
Reducer vs. Finite State Machines: Understanding the Paradigm Shift
Favicon
A tool that can be used by anyone to manage React Query state externally
Favicon
Taming the State Beast: Redux vs. Recoil in React
Favicon
11 friends of state management in Angular
Favicon
React State Management
Favicon
How Can State Management Be Applied To A Real World Case-Scenario
Favicon
No more State Management with Signals
Favicon
How to keep state between page refreshes in React
Favicon
How to sync React state across tabs with workers
Favicon
State Management Patterns in React

Featured ones: