All'alba vincerò

At dawn, I will win!

React/한입 리액트

useReducer: state 관리 코드를 컴포넌트 외부로 분리하는 React Hook

나디아 Nadia 2024. 3. 29. 20:04

 
 
 
 
 

📌 useReducer

: 컴포넌트 내부에 새로운 state를 생성하는 React Hook
 

  • 모든 useState는 useReducer로 대체가 가능하다.
  • 사실상 useState와 거의 비슷하다.
  • 상태 관리 코드를 컴포넌트 외부로 분리할 수 있다.
  • : 컴포넌트 내부에는 state 생성만 해놓고
  • 실제로 state를 관리하는 코드들은 Reducer라는 함수를 통해 컴포넌트 외부에서 관리하도록 코드를 분리할 수 있다.

 
 
 
 
 
 
 

📌 useReducer 구조

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

 
 

◽인자

  • reducer : 상태가 어떻게 업데이트할 지 명시한 함수
  • 순수 함수여야하며, 인자로 상태와 액션을 받아야 하고, 다음 상태값을 반환해야 한다.
  • 상태와 액션은 어떤 타입도 가능하다.

 

  • initialArg : state의 초기값
  • 어떤 타입의 값도 가능하다.
  • 초기 상태를 계산하는 방법은 다음에 오는 init 인자에 따라 달라진다.

 

  • init : 초기값을 반환하는 초기화 함수 (선택사항)
  • 초기화 함수가 전달되지 않은 경우 ❌ - 초기 값은 initialArg 값으로 설정된다.
  • 전달된 경우 ⭕ - 초기값은 init(initialArg)를 호출한 결과로 설정된다.

 
 
 

◽ dispatch 함수

dispatch({
     type : "구분할 이름",
     data : state 값을 어떻게 변화할지,
})

 
: 상태 변화가 있어야 한다는 사실을 알리는 함수를 반환(= dispatch)

  • dispatch: 알리다, 발송하다
dispatch({
    type : "INCREASE",
    data : 1, // 얼만큼 증가시킬지
})

 
 
 
 
 

◽ Action 객체

: 인수로 전달된 요청의 내용을 담고 있는 객체

  • dispatch 함수 내부의 객체
{
    type : "INCREASE",
    data : 1, // 얼만큼 증가시킬지
}

 
 
 
 


 

🔺 useReducer 사용하기

 
1. import로 useReducer 불러오기

import { useReducer } from "react";

 
 
 
2. useReducer 호출하기

  • 컴포넌트 내부에서 Dispatch 함수를 호출하면,
    상태 변화가 요청됨 👉 useReducer가 상태 변화를 실제로 처리하게 될 함수(직접 생성)를 호출
const [state, dispatch] = useReducer();

 


3. useReducer가 상태 변화를 실제로 처리하게 될 함수 만들기

  • reducer: 변환기
    - 상태를 실제로 변환시키는 변환기 역할
function reducer() {
    
}

 
 
 
4. 만든 함수 reducer를 useReducer의 인수로 넣기

  • 초기값도 인수로 넣어서 설정 가능
const [state, dispatch] = useReducer(reducer);

 
 
 


 
 

📌 useReducer로 카운터(Counter) 만들기

1. 컴포넌트 생성

const Exam = () => { 
...
}

 
 
 
2. useReducer 생성

const [state, dispatch] = useReducer(reducer, 0); // state 초기값: 0

 
 
 
3. 버튼의 이벤트 핸들러 함수 생성

  • dispatch 함수(state 값을 어떻게 변할지) 생성
    const onClickPlus = () => {
        // 1. dispatch 함수가 호출됨
        dispatch ({
            type : "INCREASE",
            data : 1,
        })
        // 인수: 상태가 변하길 원하는 값
    }

 
 
 
4. reducer 함수 생성

  • 인자값으로 state(초기값)와 action 객체 전달
  • 조건문(if/switch)을 통해 조건에 따라 값 변경 
    switch(action.type) {
        case "INCREASE": return state + action.data;
        case "DECREASE": return state - action.data;
        default: return state
        // 이외의 값은 그냥 state값 반환
    }

 
 
 
 
 
 

🔸 실행 과정

 
 
'+'(Plus) 버튼을 누르면
 
1. dispatch 함수가 호출됨 
2. 실제 상태를 변환시키는 reducer 함수가 실행됨 
- dispatch 함수의 action 객체("INCREASE", 1)가 reducer 함수의 매개변수로 전달되어 실행됨

 
 
3. + / - 버튼의 조건에 따라 값 변경하기
- action.type이 "INCREASE"라면 dispatch  함수가 실행됐다는 것 ➡ 버튼이 눌렸다는 것
➡ 버튼이 눌렸으면 현재 state 값에 + 1(action.date)를 해줄 것
 
 
4. reducer 함수에서 반환된 변환 값(state + action.data;)이  useReducer의 인자로 들어감

import { useReducer } from "react";

// 2. 실제 상태를 변환시키는 reducer 함수가 실행됨
function reducer(state, action) {
    // state => 0, action => "INCREASE", 1

    switch(action.type) {
        case "INCREASE": return state + action.data;
        /* action.type이 "INCREASE"라면 dispatch 함수가 실행됐다는 것 -> 버튼이 눌렸다는 것
         => 버튼이 눌렸으면 현재 state 값에 + 1(action.date)를 해줄 것 */
        case "DECREASE": return state - action.data;
        default: return state // 이외의 값은 그냥 state값 반환
    }
}

// Exam 컴포넌트
const Exam = () => {

    const [state, dispatch] = useReducer(reducer, 0); // state 초기값: 0

    // + 버튼
    const onClickPlus = () => {
        // 1. dispatch 함수가 호출됨
        dispatch ({ // dispatch 함수의 인수: 상태가 변하길 원하는 값
            type : "INCREASE",
            data : 1,
        })
    }

    // - 버튼
    const onClickMinus = () => {
        dispatch({
            type: "DECREASE",
            data: 1,
        })
    }

    return ( 
        <div>
            <h1>{state}</h1>
            <button onClick={onClickPlus}>+</button>
            {/* '+' 버튼 클릭 시 dispatch  함수를 호출(상태 변화를 요청)  */}
            <button onClick={onClickMinus}>-</button>
        </div>
    )
}

export default Exam;

 
 

 


 
 

출처

한입 크기로 잘라먹는 리액트
 

useReducer를 어떻게, 그리고 언제 사용할까?

useReducer의 문법과 사용법, 그리고 언제 useReducer를 사용하면 좋은지 알아보자.

eun-jee.com