Back to articles

Modern State Management in React: Beyond Redux

AuthorMajd Muhtaseb11/03/20257 minutes

Introduction

Redux has been a dominant force in React state management for years. However, the React ecosystem has evolved, offering more streamlined and performant alternatives. This article explores several modern approaches that address the complexities of Redux without sacrificing control or scalability.

The Context API

React's built-in Context API provides a simple and effective way to share data between components without prop drilling.

// Context Creation
import React, { createContext, useContext, useState } from 'react';

const ThemeContext = createContext();

export const useTheme = () => useContext(ThemeContext);

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  const value = { theme, toggleTheme };

  return (
    <ThemeContext.Provider value={value}>
      {children}
    </ThemeContext.Provider>
  );
};

// Component Usage
function MyComponent() {
  const { theme, toggleTheme } = useTheme();

  return (
    <div className={`App ${theme}`}>
      <button onClick={toggleTheme}>Toggle Theme</button>
      <p>Current Theme: {theme}</p>
    </div>
  );
}

export default MyComponent;

Zustand

Zustand is a small, fast, and scalable bearbones state management library. It uses a simplified API and requires minimal boilerplate.

import create from 'zustand';

const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}));

function MyComponent() {
  const { count, increment, decrement } = useStore();

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
    </div>
  );
}

export default MyComponent;

Recoil

Recoil is a state management library created by Facebook specifically for React. It offers a more granular approach to state management, allowing you to define individual "atoms" of state that components can subscribe to.

import { RecoilRoot, atom, useRecoilState } from 'recoil';

const countState = atom({
  key: 'countState',
  default: 0,
});

function MyComponent() {
  const [count, setCount] = useRecoilState(countState);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

function App() {
  return (
    <RecoilRoot>
      <MyComponent />
    </RecoilRoot>
  );
}

export default App;

Jotai

Jotai is a minimalist state management library inspired by Recoil. It focuses on simplicity and performance, offering a similar atom-based approach with a smaller bundle size.

import { atom, useAtom } from 'jotai'

const countAtom = atom(0)

function MyComponent() {
  const [count, setCount] = useAtom(countAtom)
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

export default MyComponent;

Conclusion

Choosing the right state management solution depends on the specific needs of your project. Context API works well for simple use cases, while Zustand, Recoil, and Jotai provide more robust solutions for complex applications with performance requirements. By exploring these alternatives, you can find a more suitable and efficient approach to managing state in your React applications.