React.js: useReducer();

Beautify.log·2021년 11월 2일
0
post-thumbnail

이전에 우리가 값의 변화 상태를 관리해야할 때 useState라는 Hook을 사용했습니다. 초기값을 지정해주고 변화하는 값을 반환해 줄 함수의 쌍으로 이루어진 useState로 아이디와 비밀번호에 입력하는 값이 변화될 때 어떻게 업데이트 되는지 보았습니다.

다수의 하위값을 갖는 정적 로직을 관리할 때, 이를테면 다음 state가 이전의 state에 의존적인 경우 useState 보다는 useReducer가 더욱 선호됩니다. 콜백 대신 dispatch를 전달해준다는 이유에서 자세한 업데이트를 트리거하는 컴포넌트 최적화에 더 유리합니다.

  1. 숫자 카운터 예시로 useReducer 이해하기
  2. input 상태 관리하기

숫자 카운터 예시로 useReducer 이해하기

숫자 카운터 예시를 보며 이해해보겠습니다.

import React, { useReducer } from 'react';

const initialState = { count: 0 };

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

function Counter () {
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <>
      Count: {state.count}
      <button
        onClick={() => {
          dispatch({type: 'INCREMENT'})
        }}
      >
        +
      </button>
      <button
        onClick={() => {
          dispatch({type: 'DECREMENT'})
        }}>
        -
      </button>
    </>
  )
}

useReducer의 첫번째 parameter로 reducer 함수를 사용하고, 두번째 parameter에는 해당 reducer의 default value를 넣어줍니다. 여기서 state값과 dispatch 값을 받아오는데 state는 현재 가리키고 있는 상태이며 dispatch는 액션을 발생시키는 함수입니다.

이 Hook을 사용했을 때 장점은 컴포넌트를 업데이트 하는 로직을 컴포넌트 밖으로 빼서 사용할 수 있다는 것입니다.

reducer는 현재 상태와 업데이트를 위해 필요한 정보를 담은 action 값을 전달 받아 새로운 상태를 반환해줍니다. reducer 함수에서 새로운 상태를 만들 때는 지켜야할 사항이 있는데 이를 '불변성을 지킨다'고 합니다.

switch...case~를 활용하여 불변성을 지키며 새로운 상태를 반환해줍니다.

번외적으로 Redux에서는 액션 객체가 어떤 객체인지 알려주는 type 필드가 필요하지만 useReducer에서는 꼭 그러할 필요가 없고 객체가 아닌 문자열이나 숫자가 주어져도 괜찮습니다.

input 상태 관리하기

기존에 input 상태를 관리할 때 input이 여러개 있으면 useState를 반복적으로 사용했었습니다. useReducer를 사용하여 useState의 반복사용을 피하고 클래스형 컴포넌트에서 <input />name을 할당하여 e.target.value를 참조하여 state를 set해 준 것처럼 사용할 수 있습니다.

import React, { useReducer } from "react";

function reducer(state, action) {
  return {
    ...state,
    [action.name]: action.value
  };
}

const Login = () => {
  const [state, dispatch] = useReducer(reducer, {
    id: "",
    pw: ""
  });
  const { id, pw } = state;
  const onChange = (e) => {
    dispatch(e.target);
  };

  return (
    <div>
      <div>
        <input name="id" value={id} onChange={onChange} />
        <input name="pw" value={pw} onChange={onChange} />
      </div>
      <div>
        <div>
          <b>ID: </b> {id}
        </div>
        <div>
          <b>PW: </b> {pw}
        </div>
      </div>
    </div>
  );
};

export default Login;

useReducer의 action은 어떠한 값이든 사용될 수 있습니다. 그래서 바뀌는 값을 참조할 때 e.target을 액션 자체로 사용할 수 있는 것입니다.

다음 포스트에서는 useMemo Hook에 대해 살펴보겠습니다.

profile
tried ? drinkCoffee : keepGoing;

0개의 댓글