개발 기록 남기기✍️

[React] useReducer란 무엇인가 본문

Front-End/React

[React] useReducer란 무엇인가

너해동물원 2023. 3. 13. 20:40

Redux를 공부하기 전에 잠깐!!!!

useReducer의 개념을 이해하면 Redux는 물론이고 상태 관리 라이브러리를 공부할 때 이해가 가능하다는데..?

Redux 라이브러리 공부하기 전에 Reducer부터 알아보자🏃‍♀️


💻 useReducer

useReducer는 useState 를 통한 상태 관리 및 데이터 추가/제거/수정 등의 각종 Handler를 하나의 함수로 사용할 수 있도록 해준다.

뿐만 아니라 useReducer를 사용하면 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리시킬 수 있다. 상태 업데이트 로직을 컴포넌트 바깥에 작성 할 수도 있고, 심지어 다른 파일에 작성 후 불러와서 사용 할 수도 있다.

 

즉, useReducer로 상태 관리를 하면 컴포넌트를 최적화할 수 있다.

 

// useState를 사용하는 경우
function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

useState를 사용한 경우에는 컴포넌트 내부 State 업데이트 로직이 존재한다.

 

// useReducer를 사용하는 경우
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 (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

 

useReducer를 사용하는 경우, State 업데이트 로직을 컴포넌트 외부에 작성가능하고, 별도의 파일에 담아 import 처리도 가능하다.

 

 

🧐 useReducer 🆚 useState

  • useState
    • 관리해야 할 State가 1개일 경우
    •  State가 단순한 숫자, 문자열 또는 Boolean 값일 경우
    • 상태 변경과 관련한 로직이 짧고 단순한 경우
  • useReducer
    • 관리해야 할 State가 복수일 경우
    • 상태 변경과 관련한 로직이 길고 복잡한 경우
    • State가 previous state에 크게 의존하는 경우 

 

 

💻 useReducer 구성 요소

1️⃣ useReducer

const [state, dispatch] = useReducer(reducer, initialState[, init]);
  • state: 컴포넌트에서 사용할 State
  • dispatch: reducer 함수를 실행시키며, 컴포넌트 내에서 state의 업데이트를 일으키기 위해서 사용하는 함수
  • reducer: 컴포넌트 외부에서 state를 업데이트하는 로직을 담당하는 함수. 현재의 state와 action 객체를 파라미터로 받아서, 기존의 state를 대체(replace)할 새로운 State를 반환(return)하는 함수
  • initialState: 초기 State
  • init: 초기 함수 (생략 가능)

 

2️⃣ action

action은 업데이트를 위한 정보를 가진다. dispatch의 인자가 되며, reducer 함수의 두번째 인자인 action에 할당된다.
action은 따로 정해진 형태는 없으나 주로 type라는 값을 지닌 객체 형태로 사용된다.

 

 

3️⃣ dispatch

dispatch 함수는 reducer 함수를 실행시킨다.
dispatch 함수의 인자로써 업데이트를 위한 정보를 가진 action을 이용하여, 컴포넌트 내에서 state의 업데이트를 일으키기 위해서 사용된다.
dispatch 함수의 인자인 action reducer 함수의 두번째 인자인 action에 할당된다.

dispatch({ type: "decrement" })

 

 

4️⃣ reducer

reducer 함수는 dispatch 함수에 의해 실행되며, 컴포넌트 외부에서 state를 업데이트하는 로직을 담당한다.

useReducer 함수의 첫번째 파라미터로 입력된 reducer 함수는 현재의 state와 action을 인자로 받게 되는데, 이 action의 값에 근거하여 기존의 state를 대체할 새로운 state를 반환한다.

export function 리듀서(state, action) {
  switch (action.type) {
    case '작업이름':
      return 해당 작업이름으로 dispatch 했을 때 실행될 코드
    default:
      throw new Error(`Unhandled action type: ${action.type}`)
  }
}

reducer 함수에서 type을 판별할 때 switch 문으로 작성하는 것이 관행이다.

 

 

👩‍💻 예제