본문 바로가기

3주차

[React] useState와 useReducer의 차이점

안녕하세요! 웹파트 OB 이예림입니다!

React를 사용하면서 상태 관리에 대해 고민해본 분이라면 useState와 useReducer의 차이점에 대해 한 번쯤 생각해 본 적이 있으실 텐데요~ 두 훅 모두 컴포넌트의 상태를 관리하지만, 각각의 목적과 특성이 다릅니다. 본문에서는 useState useReducer의 동작 방식과 사용해야 할 상황을 비교해보겠습니다.

✅ 간단한 상태 관리: useState

 

useState는 컴포넌트에서 상태값을 쉽게 관리할 수 있도록 도와주는 가장 기본적인 훅이다. 입력 필드의 값, 체크박스 상태 등 비교적 간단한 상태를 다룰 때 자주 사용된다.

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);

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

본 예제에서 useState는 간단한 숫자 상태를 관리하기 때문에 적합하다. 하지만 관리해야 하는 상태가 복잡해질 경우, useState는 코드의 가독성을 떨어뜨릴 수 있다.

✅ 복잡한 상태 관리: useReducer

 

useReducer는 보다 복잡한 상태나 여러 동작이 필요한 상태 관리에 적합하다. useReducer는 상태와 상태 업데이트하는 로직을 하나의 리듀서 함수로 묶어, 코드의 가독성과 확장성을 높여준다.

import { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

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

위 예제는 useState를 사용할 때보다 구조가 복잡해 보이지만, 상태의 변경 규칙이 명확해 관리가 쉽다. 특히 상태 관리 로직이 여러 컴포넌트에 걸쳐있을 때 유용하다.

🤔 언제 useState 대신 useReducer를 사용해야 할까?

useReducer가 유리한 경우

 

1️⃣ 상태가 복잡할 때 : 여러 개의 상태값을 다뤄야 하거나 상태 값이 여러 가지 액션을 처리해야 하는 경우
2️⃣ 상태 관리 로직을 분리해야 할 때 : 상태 변경 로직을 한 곳에 모아두면, 추후 코드 수정이 편리하다.

3️⃣ 컴포넌트 트리 구조가 깊고 하위 컴포넌트들이 상태를 공유할 때

: 상태 관리가 명확해지므로 리액트에서 데이터 흐름이 투명해진다.

 

useState가 유리한 경우

 

1️⃣ 단순한 상태를 다룰 때 : 단일 값이거나, 단순히 값을 증가시키는 정도의 상태인 경우
2️⃣ boolean 상태일 때 : 단순히 참/거짓으로 상태를 다루는 경우

 

✅ 성능 및 유지보수 관점에서의 차이

  • 성능두 훅 모두 가벼운 편이지만, useReducer는 컴포넌트가 매번 렌더링되지 않도록 복잡한 상태 변경을 효과적으로 관리할 수 있다. 특히 상태가 복잡하거나 여러 액션이 한꺼번에 일어날 때 유리하다.
  • 유지보수useReducer는 상태와 변경 로직을 중앙에서 관리하기 때문에, 기능이 복잡해질수록 코드가 체계적으로 정리된다.

 

✅ 결론

어떤 상황에 어떤 훅을 선택해야할까?

  • 세미나 자료 참고!!
    🧐 useReducer vs useState
    관리해야하는 state 1개일 경우 관리해야 할 state가 복잡한 객체일 경우
    그 state 가 단순한 숫자, 문자열 또는 Boolean 값일 경우 현재는 단일 state 값만 관리하지만, 추후 복잡해질 가능성이 있어
    유지보수를 용이하게 하려는 경우  

리액트에서 useState와 useReducer는 상태를 관리하는 방식에서 큰 차이를 보여준다. 작은 프로젝트에서는 useState가 대부분 충분하지만, 관리해야할 상태가 복잡해질수록 useReducer가 더 적합할 때가 많다. 리액트의 상태 관리 방식을 더 깊이 이해하고, 컴포넌트의 역할과 상태 복잡도에 따라 적절한 훅을 선택하는 것이 중요하다!