[React] useReducer

Byeonghyeon·2025년 1월 12일

공부

목록 보기
3/21

useReducer

useReducer는 useState와 마찬가지로 state를 관리하는 Hook이다.

useState vs useReducer

useState는 기본적인 상태 관리 Hook이며, 주로 간단한 상태를 관리할 때 사용한다.

그 반면 useReducer는 useState보다 더 복잡한 로직을 처리할 때 유리하다.

useReducer를 사용한 코드의 예시

function ageReducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { age: state.age + 1 };
    case 'decrement':
      return { age: state.age - 1 };
    default:
      return state;
  }
}

function App() {
  const [state, dispatch] = useReducer(ageReducer, {age: 25});

  const incrementAge = () => {
    dispatch({ type: 'increment' });
  }

  const decrementAge = () => {
    dispatch({ type: 'decrement' });
  }

  return(
    <div>
     <p>나이 : {state.age}</p>
     <button onClick={incrementAge}>1년 후</button>
     <button onClick={decrementAge}>1년 전</button>
    </div>
  );
}

매개변수

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

  • reducer : state가 어떻게 업데이트 되는지 지정하는 리듀서 함수이다. 리듀서 함수는 반드시 순수 함수여야 하며, state와 action을 인수로 받아야하고, 다음 state를 반환해야 한다. state와 action에는 모든 데이터 타입이 할당될 수 있다.
  • initialArg : 초기 state가 계산되는 값이다. 모든 데이터 타입이 할당될 수 있다. 초기 state가 어떻게 계산되는지는 다음 init 인수에 따라 달라진다.
  • optional init : 초기 state를 반환하는 초기화 함수이다. 이 함수가 인수에 할당되지 않으면 초기 state는 initialArg로 설정된다. 할당되었다면 초기 state는 init(initialArg)를 호출한 결과가 할당된다.

반환값

useReducer는 2개의 엘리먼트로 구성된 배열을 반환한다.

  1. 현재 state. 첫번째 렌더링에서의 state는 init(initialArg) 또는 initialArg로 설정된다.
  2. dispatch 함수. dispatch는 state를 새로운 값으로 업데이트하고 리렌더링을 일으킨다.

언제 사용해야 할까?

위에 작성한 useState를 사용한 코드와 useReducer를 사용한 코드를 비교해보면 useState를 사용한 쪽이 훨씬 간단하게 작성된 것을 볼 수 있다.

하지만 useReducer는 state의 형태가 복잡할 때 진가를 발휘한다.

const initialState = {
  name: 'Stroud',
  age: 25,
  address: {
    country: "USA",
    city: "Houston"
  }
}

이런 상태가 있다고 가정했을 때 한국으로 이사하는 로직을 추가한다면,

setState(prevState => ({
      ...prevState, address: {...state.address, country: 'Korea'}
    }));

useState를 사용했을 때는 컴포넌트 내부에 이렇게 작성해줘야 할 것이다.

하지만 useReducer를 사용했다면,

dispatch({ type: 'MOVE_TO_KOREA' });

매우 간단하다!

function reducer(state, action) {
  switch (action.type) {
    case 'MOVE_TO_KOREA':
      return { ...state, address: {...state.address, country: 'Korea'} };
    case 'MOVE_TO_JAPAN':
      return { ...state, address: {...state.address, country: 'Japan'} };
    default:
      return state;
  }
}

물론, 그에 따라 reducer 함수에도 추가 연산을 작성해줘야하지만, Component 내부에서 복잡한 코드를 줄일 수 있다는 장점이 있다.

0개의 댓글