[React] useReducer

pyozz·2024년 1월 22일
post-thumbnail

useReducer란?

useState와 같이 상태 관리를 위한 훅인데 상태 관리 뿐만 아니라 그 상태에 대한 변화(추가, 제거, 수정 등)와 관련된 handler를 하나의 함수로 모아서 사용할 수 있도록 한다. 그리고 이 상태 업데이트 로직 함수를 분리시켜서 다른 파일에서 불러와서 사용할 수도 있다.

기본적인 형태는 다음과 같다.

리듀서 함수 내부에서 컴포넌트 함수 내부에서 만들어진 어떤 데이터도 필요하지 않다면 컴포넌트 외부에 작성해도된다. (상호작용x)

const [state, dispatch] = useReducer(reducer, initialState)
  • state 말 그대로 상태를 의미한다.
  • dispatch 어떤 유형의 작업을 할지 reducer에게 알리면서 reducer 함수를 호출한다. dispatch(작업 이름) 과 같이 입력하는데 작업 이름을 입력 받았을 때 어떤 작업을 수행할 지는 정해진게 없는데 이 작업을 정의하는 부분이 reducer이다. (보통 type: 작업이름 이라고 인자를 명시하는 것이 관행이다.)
  • reducer state 변화와 관련된 코드들이 모아져 있는 곳 dispatch에 작업 이름이 들어왔을 때, 그 이름에 맞는 작업 내용이 reducer 함수에서 실행된다. 예시는 다음과 같다.
export function reducer(state, action) {
  switch (action.type) {
    case '작업이름':
      return 해당 작업이름으로 dispatch 했을 때 실행될 코드
    default:
      throw new Error(`Unhandled action type: ${action.type}`)
  }
}

사용 예시를 하나 작성하면 다음과 같다.

import React, { useReducer, useState } from 'react'
import { userData } from '../constants/userData'
import { userReducer } from '../reducers/userReducer'

function UserList() {
  const [state, dispatch] = useReducer(userReducer, userData)

  return (
    <div>
      {state.map((user) => (
        <h3>{user.name}</h3>
      ))}

	  <button onClick={() => dispatch({ type: 'ADD', data: { name: 'Lee' } })}>
  		유저 추가
      </button>
    </div>
  )
}

export default UserList
export function userReducer(state, action) {
  switch (action.type) {
    // dispatch({type: 'ADD', data: 새로운 유저 데이터})
    case 'ADD':
    // 여기서 return된 값이 state로서 할당되어 관리된다.
     return [...state, action.data]

    default:
      throw new Error('해당 액션 타입이 없습니다')
  }
}
  • 여러 state가 서로 관련이 있거나
  • state가 다른 state에 의해 업데이트 되는 경우 useReducer 훅을 사용하여 하나의 state로 병합하는 것도 좋다. 물론, state를 객체로 관리하여 각 프로퍼티 값이 관련 있다는 것을 알리는 방법도 있지만, state가 복잡해지거나 하면 useReducer 훅을 사용하는 것이 좋다. 리액트 state 업데이트 스케줄링 문제가 있는데 즉, 변하지 않은 이전의 state를 참조하게 될 수도 있는 것이다.

0개의 댓글