🔷 React

[React] useReducer

코딩하세현 2025. 4. 23. 11:06
728x90

📘 useReducer

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

모든 useState는 useReducer로 대체 가능

 

useReducer를 이용하면 어떤 차이점이 있냐?

상태 관리 코드를 컴포넌트 외부로 분리 가능

 

useState - App 컴포넌트를 벗어나면 안돼~😢 가지마~

 

React Components의 주된 역할은 무엇일까요?
👨🏻‍🏫 UI를 관리하는 것

 

✨ 동작 순서

더보기

1. 사용하고자 하는 상태관리를 import를 통해서 불러온다.

2.  컴포넌트 안에서 변수로 Hook을 불러와준다.

3. 컴포넌트 내부에서 dispatch함수를 호출한다.

4. UseReducer()가 상태 변화를 실제로 처리하게될 함수를 호출하며 작동한다.

5. 처리할 함수를 직접 만들기

 

🔍 dispatch

import React, { useReducer } from 'react';

// dispatch: 발송하다, 급송하다
const [state, dispatch] = useReducer();

const [새로운 state를 생성해서 배열의 첫번째 요소로 반환, 상태 변화를 요청하기만 하는 함수] = useReducer();

 

dispatch의 의미는 발송하다, 급송하다의 의미이다.

즉, dispatch함수는 상태변화가 있어야 한다는 사실을 알리는, 발송하는 함수이다. 

import React, { useReducer } from 'react';

const Exam = () => {
  const [state, dispatch] = useReducer();
  return (
    <div>
    	...
    </div>
  );
};

export default Exam;

🔍 Reducer

Redcuer란?

상태를 실제로 변환시키는 변환기 역할을 한다. 

import React, { useReducer } from 'react';

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

const Exam = () => {
  // dispatch: 변환기에게 상태를 변환하라고 요청하는 역할
  // useReducer: 상태를 변환하는 변환기 역할을 하는 훅
  const [state, dispatch] = useReducer(reducer, 0);
  return (
    <div>
      <h1>0</h1>
      <button>+</button>
    </div>
  );
};

export default Exam;

 

function Reducer() 함수를 만들어준다. 

 

cosnt [state, dispatch] = useRedcuer(번째 인수 , 번째 인수)

번째 인수에는 Reducer() 함수를 넣어주고

번재 인수로는 State의 초기 값을 전달할 수 있다.

 

import React, { useReducer } from 'react';

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

const Exam = () => {
  // dispatch: 변환기에게 상태를 변환하라고 요청하는 역할
  // useReducer: 상태를 변환하는 변환기 역할을 하는 훅

  // useReducer인수에 reducer함수를 넣어주기!
  const [state, dispatch] = useReducer(reducer, 0);
  return (
    <div>
      {/* state값을 렌더링하기 */}
      <h1>{state}</h1>
      <button>+</button>
    </div>
  );
};

export default Exam;

 

button을 누르면 state의 값을 1씩 증가시켜야한다. 

 

? 🙄

컴포넌트 내부에서 버튼이 클릭되었을 때 dispatch 함수를 호출해 상태 변화를 발송(요청)한다.

import React, { useReducer } from 'react';

function reducer() {}

const Exam = () => {
  // 이벤트 만들어주고
  const onClickPlus = () => {};

  const [state, dispatch] = useReducer(reducer, 0);
  return (
    <div>
      <h1>{state}</h1>
        {/* 버튼에 onClick 이벤트 handler 추가하기 */}
      <button onClick={onClickPlus}>+</button>
    </div>
  );
};

export default Exam;

 

onClickPlus 함수안에서 dispatch를 호출해 상태 변화를 요청하면 된다

import React, { useReducer } from 'react';

function reducer() {}

const Exam = () => {
  // 1. 이벤트 만들어주고
  const onClickPlus = () => {
    // 3. onClickPlus 함수안에서 dispatch를 호출해 상태 변화를 요청
    dispatch();
  };

  const [state, dispatch] = useReducer(reducer, 0);
  return (
    <div>
      <h1>{state}</h1>
      {/* 2. 버튼에 onClick 이벤트 handler 추가하기 */}
      <button onClick={onClickPlus}>+</button>
    </div>
  );
};

export default Exam;

 

dispatch의 인수로 상태가 어떻게 변화되길 원하는지 그 정보를 전달해준다. 

dispatch 함수에는 객체 형태로 타입이라는 프로퍼티에는 상태를 어떻게 변화시키길 원하는지 작성해준다. 

  const onClickPlus = () => {
    dispatch({
      // 인수로는 상태가 어떻게 변화하기 원하는지 정보 전달하기
      type: '',
    });
  };

이번 실습에서는 버튼을 누를때마다 증가시킴으로

data를 작성해 프로퍼티를 1씩 증가시키라고 전달한다.

const Exam = () => {
  // 1. 이벤트 만들어주고
  const onClickPlus = () => {
    // 3. onClickPlus 함수안에서 dispatch를 호출해 상태 변화를 요청
    dispatch({
      // 4. 인수로는 상태가 어떻게 변화하기 원하는지 정보 전달하기
      type: 'INCREASE',
      data: 1,
    });
  };

 

type, data같이 정보전달하는 인수들을 action 객체라고 부른다.

 

action 객체를 전달하면서 Dispatch 함수를 호출해주면 useReducer가 이 요청을 처리해주기 위해 실제 상태를 변화시키는 Reducer 함수를 호출한다. 

Reducer 함수의 매개변수에는 현재 state값을 제공하고 두번째는 요청이 담긴 Action 객체를 제공해준다. 

function reducer(state, action) {}

 

const onClickPlus안에 있는 dispatch를 호출하게 되면 reudcer함수가 호출이 되고

dispatch안에 있는 action객체가 reducer함수의 매개변수로 전달이 된다. 😯

function reducer(state, action) {
  console.log(state, action);
}

  +버튼을 누르면 큰솔에 값인 0과 action이 호출되는 것을 볼 수 있다. 

 

 reducer 함수는 매개변수로 받은 현재의 state값과 action객체를 이용해 실제 state 값을 변경시키면 된다.

 

상태 변화 함수도 없는데 어떻게 state함수를 변경시킬까?🤔 

→ 💡 Redcue 함수에서 새 state값을 반환시키면 된다. 

  const [state, dispatch] = useReducer(reducer, 0);

→ 반환된 값은 useReducer가 불러와 실제로 이 state값을 변경시킨다. 

 

return안에 이렇게 작성하면 된다. 

function reducer(state, action) {
  if (action.type == 'INCREASE') {
    return state + action.data;
  }
  console.log(state, action);
}

 

이제는 상태 변화도 추가적으로 만들어보겠다. 마이너스 버튼 역시 만들어줬다. 

import React, { useReducer } from 'react';

// reducer: 변환기
// -> 상태를 실제로 변환시키는 변환기 역할
function reducer(state, action) {
  if (action.type == 'INCREASE') {
    return state + action.data;
  } else if (action.type == 'DECREASE') {
    return state - action.data;
  }
  console.log(state, action);
}

const Exam = () => {
  // 1. 이벤트 만들어주고
  const onClickPlus = () => {
    // 3. onClickPlus 함수안에서 dispatch를 호출해 상태 변화를 요청
    dispatch({
      // 4. 인수로는 상태가 어떻게 변화하기 원하는지 정보 전달하기
      type: 'INCREASE',
      data: 1,
    });
  };

  const onClickMinus = () => {
    dispatch({
      type: 'DECREASE',
      data: 1,
    });
  };

  // dispatch: 변환기에게 상태를 변환하라고 요청하는 역할
  // useReducer: 상태를 변환하는 변환기 역할을 하는 훅

  // useReducer인수에 reducer함수를 넣어주기!
  const [state, dispatch] = useReducer(reducer, 0);
  return (
    <div>
      {/* state값을 렌더링하기 */}
      <h1>{state}</h1>
      {/* 2. 버튼에 onClick 이벤트 handler 추가하기 */}
      <button onClick={onClickPlus}>+</button>
      <button onClick={onClickMinus}>-</button>
    </div>
  );
};

export default Exam;

 

Reducer 함수안에 if문이 많아질거같으면 switch문으로 변경해야한다.

/**
function reducer(state, action) {
  if (action.type == 'INCREASE') {
    return state + action.data;
  } else if (action.type == 'DECREASE') {
    return state - action.data;
  }
  console.log(state, action);
}
  */
  
  
  function reducer(state, action) {
  switch (action.type) {
    case 'INCREASE':
      return state + action.data;
    case 'DECREASE':
      return state - action.data;
    default:
      return state;
  }
}

 

728x90