React Hook - useReducer 사용하기

2025. 2. 11. 18:19개발자 블로깅/React

React

0. useReducer란?

useReducer 는 컴포넌트에 reducer 를 추가하는 React Hook 입니다.

const [state, dispatch] = useReducer(reducer, initialArg, init?)

useReducer의 매개변수

 

  • reducer : state가 어떻게 업데이트 되는지 지정하는 reducer 함수
    반드시 순수 함수로 state와 action을 인수로 받고, 다음 state를 반환해야 합니다.
    state와 sction에는 모든 데이터 타입이 할당 될 수 있음

  • initialArg : 초기 state가 계산되는 값
    모든 데이터 타입이 할당 될 수 있고 초기 state가 어떻게 계산되는지는 다음 init인수에 따라 달라짐
  • init (선택사항) : 초기 state를 반환하는 초기화 함수
    이 함수가 인수에 할당되지 않으면 초기 state는 initalArr로 설정 됨
    할당 되었다면? 초기 state는 init(initialArg)를 호출한 결과가 할당 됨 

1. Reducer 함수 정의하기

function reducer(state, action) {
  // ...
}

복붙 할 수 있는 템플릿

더보기
export default function 네이밍Reducer(state, action) {
    switch(ation.type){
        case '' : {

        }
        case '' : {
            
        }
        case '' : {
            
        }
        case '' : {
            
        }
        default: {
            throw Error ('알 수 없는 액션 타입:' + action.type);
        }
    }
}

예시

function reducer(state, action) {
  switch (action.type) {
    case 'incremented_age': {
      return {
        name: state.name,
        age: state.age + 1
      };
    }
    case 'changed_name': {
      return {
        name: action.nextName,
        age: state.age
      };
    }
  }
  throw Error('Unknown action: ' + action.type);
}

- state를 계산할 코드를 작성
- 계산된 state를 반환
- 보통 컨벤션에 따라 switch 문을 사용
- switch 는 각 case를 이용해 다음 state를 계산하고 반환함

- action 은 다양한 형태가 될 수 있지만 일반적으로 컨벤션에 따라 무엇인지 정의하는 type 프로퍼티를 포함한 객체로 선언
- type 은 reducer가 다음 state를 계산하는데 필요한 최소한의 정보를 포함해야 함

 

2. 사용법

컴포넌트에 reducer추가하기

import { useReducer } from 'react';

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, { age: 42 });
  // ...

컴포넌트에 reducer 추가하기 예시

import { useReducer } from "react";

...

  const [todos, dispatch] = useReducer(todoReducer, [
  	{ id: 0, text: "HTML&CSS 공부하기" },
    { id: 1, text: "자바스크립트 공부하기" },
  ]);

  // type이 "added_index" 해당 index에서 투두리스트 추가
   const handleAddTodoByIndex = () => {
        dispatch({
          type: "added_index",
          insertAt,
          nextId: todos.length,
          todoText,
        });
        todoText("");
      };

  // type이 "added"  투두리스트 추가
  const handleAddTodo = (e) => {
    dispatch({
      type: "added",
      nextId: todos.length,
      todoText,
    });
    setTodoText("");
  };
  
  // type이 "deleted" 투두리스트 삭제
  const handleDeleteTodo = (deleteId) => {
    dispatch({
      type: "deleted",
      deleteId,
    });
  };

...

 

주의!!

state는 읽기 전용으로 stste의 객체나 배열을 직접 변경하지 마세요!

잘못된 예시 코드

function reducer(state, action) {
  switch (action.type) {
    case 'incremented_age': {
      // 🚩잘못된 코드
      state.age = state.age + 1;
      return state;
    }

 

올바른 예시 코드

function reducer(state, action) {
  switch (action.type) {
    case 'incremented_age': {
      // ✅ 새로운 object 로 return
      return {
        ...state,
        age: state.age + 1
      };
    }

 

참고 
https://ko.react.dev/reference/react/useReducer#writing-the-reducer-function