반응형

🚀 useReducer()

React에서 컴포넌트의 상태 관리를 위해서 useState를 사용해서 상태를 업데이트를 하는데, useReducer를 사용하게 되면 컴포넌트와 상태 업데이트 로직을 분리하여 컴포넌트 외부에서도 상태 관리를 할 수 있습니다. 즉, 현재 컴포넌트가 아닌 다른 곳에 state를 저장하고 싶을 때 유용하게 사용할 수 있습니다. 

 

useReducer 사용법

const [state, dispatch] = useReducer(reducer, initialState);
  • state : 현재 상태
  • dispatch : action을 발생시키는 함수
  • reducer : state와 action를 받아 새로운 state를 반환하는 함수
  • initialState : 초기값
// 리듀서 함수 예시
function reducer(state, action) {
  switch (action.type) { // 액션 타입
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

 

useReducer 예제

리액트 reducer를 공부할 때 항상 나오는 Counter 예제를 통해 useReducer를 적용해보겠습니다.
(useState 함수를 사용한 Counter.jsx와 비교)

// App.js

import React, { useState } from "react";
import Counter from "./components/Counter";

const App = () => {
  return (
    <div style={{ position: "absolute", top: "50%", left: "50%" }}>
      <Counter />
    </div>
  );
};

export default App;

useState를 사용한 Counter.jsx

// ./components/Counter.jsx

import React, { useState } from "react";

function Counter() {
  const [number, setNumber] = useState(0);

  const onIncrease = () => {
    setNumber((prevNumber) => prevNumber + 1);
  };

  const onDecrease = () => {
    setNumber((prevNumber) => prevNumber - 1);
  };

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

useReducer를 사용한 Counter.jsx

// ./components/Counter.jsx

import React, { useReducer } from "react";

function reducer(state, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

function Counter() {
  const [number, dispatch] = useReducer(reducer, 0);

  const onIncrease = () => {
    dispatch({ type: "INCREMENT" });
  };
  const onDecrease = () => {
    dispatch({ type: "DECREMENT" });
  };

  return (
    <div>
      <h1>{number}</h1>
      <button onClick={onIncrease}>+1</button>
      <button onClick={onDecrease}>-1</button>
    </div>
  );
}

export default Counter;

 

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

: 현재 상태 값에 number라는 이름을 주고 액션을 발생시키는 함수 dispatch를 가져옵니다. 그리고 useReducer 함수의 첫 번째 인자로 reducer함수, 두 번째 인자로 초기값은 0으로 설정!

const onIncrease = () => {
    dispatch({ type: "INCREMENT" });
  };

: 액션이 필요한 함수에 dispatch를 호출하고 인자로 객체 형식으로 type을 넣어줍니다.

<button onClick={onIncrease}>+1</button>

버튼 클릭 시 onIncrease 함수가 실행되고 dispatch로 reducer에 'INCREMENT'라는 액션 타입을 전달해줍니다.

function reducer(state, action) {
  switch (action.type) {
    case "INCREMENT":
      return state + 1;
    case "DECREMENT":
      return state - 1;
    default:
      return state;
  }
}

그렇다면 reducer에서 action.type이 'INCREMENT'이므로 현재 state에서 +1 한 값을 리턴해줍니다.

 

useState VS useReducer 

useState와 useReducer는 상황에 따라 적절하게 사용하시면 될 것 같습니다.
컴포넌트에서 관리하는 state의 수가 적다 => useState
컴포넌트에서 관리하는 state의 수가 많고 state를 변경하는 함수가 많다 => useReducer

 

 

반응형

+ Recent posts