본문 바로가기
React

React에서 useReducer 훅 사용법

by 굿센스굿 2024. 12. 11.
반응형

 

React에서는 상태 관리를 위해 가장 많이 사용하는 훅이 useState입니다. 하지만 상태가 복잡하거나 여러 작업을 체계적으로 관리해야 하는 경우, useReducer 훅이 더 적합할 수 있습니다. 이번 글에서는 useReducer 훅의 사용법, 주요 개념, 그리고 다양한 예제를 통해 실제로 어떻게 활용할 수 있는지 알아보겠습니다.


1. useReducer란 무엇인가?

useReducer는 React의 훅 중 하나로, 컴포넌트 상태를 관리하기 위해 사용됩니다. 이 훅은 Redux와 유사한 방식으로 작동하며, 액션과 리듀서를 기반으로 상태를 업데이트합니다.

useReducer의 기본 구조는 다음과 같습니다:

const [state, dispatch] = useReducer(reducer, initialState);
  • reducer: 상태 업데이트 로직을 정의하는 함수입니다. reducer는 현재 상태와 액션을 받아 새로운 상태를 반환합니다.
  • initialState: 상태의 초기값입니다.
  • state: 현재 상태를 나타냅니다.
  • dispatch: 액션을 발생시키는 함수로, 이를 통해 상태 업데이트를 요청합니다.

2. useReducer의 동작 원리

useReducer는 세 가지 주요 요소로 구성됩니다:

2.1 Reducer 함수

리듀서는 순수 함수로, 현재 상태와 액션 객체를 받아 새로운 상태를 반환합니다.

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('Unknown action type');
  }
}

2.2 Initial State

리듀서에서 사용할 상태의 초기값을 정의합니다. 이는 컴포넌트가 처음 렌더링될 때 설정됩니다.

const initialState = { count: 0 };

2.3 Dispatch 함수

dispatch는 액션 객체를 리듀서에 전달하여 상태를 업데이트하는 역할을 합니다.

dispatch({ type: 'INCREMENT' });
dispatch({ type: 'DECREMENT' });

3. 간단한 카운터 예제

useReducer를 활용해 간단한 카운터 컴포넌트를 만들어 보겠습니다.

import React, { useReducer } from 'react';

// 1. Reducer 함수 정의
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('Unknown action type');
  }
}

// 2. 초기 상태 정의
const initialState = { count: 0 };

function Counter() {
  // 3. useReducer 훅 사용
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
    </div>
  );
}

export default Counter;

위 예제에서 dispatch를 사용해 액션을 보냄으로써 상태를 업데이트합니다.


4. 복잡한 상태 관리 예제: Todo 리스트

useReducer는 상태가 복잡한 경우 특히 유용합니다. 예를 들어, Todo 리스트 관리에 활용해 보겠습니다.

import React, { useReducer, useState } from 'react';

// 1. Reducer 함수 정의
function reducer(state, action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, { id: Date.now(), text: action.payload, completed: false }];
    case 'TOGGLE_TODO':
      return state.map(todo =>
        todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
      );
    case 'REMOVE_TODO':
      return state.filter(todo => todo.id !== action.payload);
    default:
      throw new Error('Unknown action type');
  }
}

// 2. 초기 상태 정의
const initialState = [];

function TodoApp() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const [text, setText] = useState('');

  const handleAddTodo = () => {
    dispatch({ type: 'ADD_TODO', payload: text });
    setText('');
  };

  return (
    <div>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="Add a new todo"
      />
      <button onClick={handleAddTodo}>Add</button>

      <ul>
        {state.map(todo => (
          <li key={todo.id}>
            <span
              style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
              onClick={() => dispatch({ type: 'TOGGLE_TODO', payload: todo.id })}
            >
              {todo.text}
            </span>
            <button onClick={() => dispatch({ type: 'REMOVE_TODO', payload: todo.id })}>
              Remove
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default TodoApp;

이 Todo 앱은 다음 기능을 포함합니다:

  • Todo 추가
  • Todo 완료/미완료 토글
  • Todo 삭제

useReducer를 통해 각 액션을 분리하고, 상태 관리를 체계적으로 처리할 수 있습니다.


5. 언제 useReducer를 사용해야 할까?

useReducer는 다음과 같은 상황에서 유용합니다:

  • 상태가 복잡하거나 여러 하위 상태로 나뉘어 있는 경우
  • 상태 업데이트 로직이 여러 단계로 이루어진 경우
  • 상태 관리 로직을 컴포넌트 외부로 분리하고 싶은 경우

useState와 비교했을 때 useReducer는 더 명확한 상태 관리 패턴을 제공합니다. 특히, 상태 변화가 다양한 액션에 따라 이루어질 때 유용합니다.


6. 결론

useReducer는 React에서 강력한 상태 관리 도구로, 상태가 복잡하거나 여러 작업을 체계적으로 관리해야 할 때 유용합니다. 이번 글에서는 useReducer의 기본 개념과 활용법, 그리고 실제 예제를 통해 어떻게 적용할 수 있는지 알아보았습니다.

프로젝트에서 상태 관리가 복잡해질 경우, useReducer를 활용해 코드의 가독성과 유지보수성을 높여 보세요!

반응형