Redux vs Context API: Which to Choose for React State Management?

2024. 11. 2. 17:00 개발 이야기/JavaScript

When developing a React application, managing state is something that every developer grapples with. It can be especially challenging to decide which tool to use for managing global state. Today, we will dive into two popular methods of managing state in React: Redux and Context API. We will explore their usage at a code level, their key features, use cases, and differences.

What is Redux?

Redux is a library for managing the global state of an application in a centralized manner. It is widely used in React applications to increase predictability and maintainability of the state.

Key Features of Redux

  • Centralized Store: All global states are managed in a single store, making them accessible from any component in the app.
  • Immutability: State is never changed directly. Instead, a new state is returned using reducer functions to update the state.
  • Actions and Reducers: Actions, which describe what happened, are separate from reducers, which handle state updates. This makes the application structure clear.
  • Middleware: Middleware like Redux Thunk or Saga can be used to handle asynchronous operations.

How to Use Redux

Here is a simple overview of how Redux can be used.

1. Installation

To use Redux, you need to install redux and react-redux.

npm install redux react-redux

2. Basic Structure

Redux revolves around three key elements: Actions, Reducers, and the Store.

  • Action: An object that describes what happened.
  • Reducer: A pure function that takes the current state and an action, then returns a new state.
  • Store: An object that holds the entire state of your application.
// actions.js
export const increment = () => ({
  type: 'INCREMENT'
});

// reducer.js
const initialState = { count: 0 };

const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { ...state, count: state.count + 1 };
    default:
      return state;
  }
};

export default counterReducer;

// store.js
import { createStore } from 'redux';
import counterReducer from './reducer';

const store = createStore(counterReducer);
export default store;

3. Connecting Redux to React

To use Redux in React components, you need to provide the store using Provider and use hooks like useSelector and useDispatch to interact with the state.

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

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

// App.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment } from './actions';

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

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
    </div>
  );
}

export default App;

What is Context API?

The Context API is a state management tool built into React that allows you to propagate data throughout the component tree without passing props at every level. This can help avoid the "prop drilling" problem.

Key Features of Context API

  • Provider and Consumer: The Context API consists of a Provider to supply data and a Consumer to consume it. Typically, the useContext hook is used to simplify consuming data.
  • Simple Global State Management: It is suitable for small projects or simple state sharing, but it can become difficult to manage as state complexity grows.

How to Use Context API

1. Creating a Context

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

// Creating Context
const CountContext = createContext();

export function CountProvider({ children }) {
  const [count, setCount] = useState(0);
  return (
    <CountContext.Provider value={{ count, setCount }}>
      {children}
    </CountContext.Provider>
  );
}

export function useCount() {
  return useContext(CountContext);
}

2. Using Context

// App.js
import React from 'react';
import { CountProvider, useCount } from './CountContext';

function Counter() {
  const { count, setCount } = useCount();
  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

function App() {
  return (
    <CountProvider>
      <Counter />
    </CountProvider>
  );
}

export default App;

Comparison of Redux and Context API

FeatureReduxContext API

State Storage Centralized Store React's built-in Context
State Changes Immutable changes via actions Directly via setState
Asynchronous Support Middleware (e.g., Thunk, Saga) Not supported natively
Scale & Complexity Suitable for large-scale apps Suitable for small-scale apps
Re-render Optimization Prevents unnecessary re-renders Can trigger re-renders in all consumers when context value changes

When Should You Use Redux?

Redux is ideal for large-scale applications or situations where state management is complex. If you need to share the same state across multiple components or handle many asynchronous tasks (like API calls), Redux is advantageous. Centralized state management and immutability also help when traceability and scalability are essential.

When Should You Use Context API?

The Context API is well-suited for managing simple global states. It is easy to set up and use in small applications where state complexity is low. For example, it is useful for managing global states that change infrequently, such as user authentication or app themes.

Conclusion

Both Redux and Context API have their pros and cons, and it is important to choose the right tool based on the scale and complexity of your application. If your application needs complex asynchronous logic and scalable state management, consider using Redux. If you need to quickly share global state in a simple manner, the Context API could be the better option.

Choose the tool that fits your project best to implement efficient state management.