개발공작소
article thumbnail
728x90

 

 

 

 

useReducer 훅이란?

 

useReducer

useReducer는 컴포넌트에 reducer를 추가하는 React Hook입니다. -- react 공식문서

 

 

어렵게 생각하지 않아도 된다.

 

그냥 useState와 같이 컴포넌트의 상태를 관리하기 위한 react의 훅인데,

useState와는 달리 컴포넌트 내부에서가 아닌 외부에서도 컴포넌트의 상태를 관리 할 수 있도록 도와주는 훅이다..

 

useReducer를 사용하면 컴포넌트 외부에서도 상태 관리 코드를 작성할 수 있게 되기 때문에

복잡한 상태관리 로직을 모듈로 빼서, 컴포넌트 코드의 가독성을 높일 수 있다...

 

대충 그려봄..

 

 

컴포넌트라는게 UI랜더링을 하기 위해 사용하고 이 랜더링을 위해 필요한 게 컴포넌트의 상태관리이다.

근데, state가 점점 많아지고, 로직이 복잡해지면?... 하나의 컴포넌트에 state관리 코드만 몇백줄이 넘어가고

그럼 코드가 복잡해진다.. 함수가 많아지면 많아질수록 관리하기도 힘들

 

이렇게 되는 이유는 useState 훅의 기능적인 문제인데, useState 훅은 사용하고자 하는 훅 내에서만

사용가능하다. 그렇기 때문에 상태관리 코드를 해당 컴포넌트 내에서만 작성해야 했는데,

 

useReducer라는 훅을 사용하면 컴포넌트 내부에서만이 아니라, 컴포넌트 외부에서 상태관리를 할 수 있게 된다.

 

그렇기 때문에 기존 javascript 모듈처럼 상태관리 로직은 .js에 작성하여 모듈을 import하여

사용할 수 있게 되고, 컴포넌트 내부에는 복잡한 상태관리 코드를 작성하지 않아도 된다..

 

 

결론은 useReducer는 컴포넌트 외부에서도 컴포넌트의 state 상태관리를 할 수 있도록 도와주는 훅이다.

 

 

useReducer 훅 기본문법

 

기본문법

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

 

 

반환값 

useReducer는 2개의 엘리먼트로 구성된 배열을 반환합니다.

  1. 현재 state. 첫번째 렌더링에서의 state는 init(initialArg) 또는 initialArg로 설정됩니다 (init이 없을 경우 initialArg로 설정됩니다).
  2. dispatch 함수. dispatch는 state를 새로운 값으로 업데이트하고 리렌더링을 일으킵니다.

 

매개변수 

  • reducer: state가 어떻게 업데이트 되는지 지정하는 리듀서 함수입니다. 리듀서 함수는 반드시 순수 함수여야 하며, state와 action을 인수로 받아야 하고, 다음 state를 반환해야 합니다. state와 action에는 모든 데이터 타입이 할당될 수 있습니다.
  • initialArg: 초기 state가 계산되는 값입니다. 모든 데이터 타입이 할당될 수 있습니다. 초기 state가 어떻게 계산되는지는 다음 init 인수에 따라 달라집니다.
  • 선택사항 init: 초기 state를 반환하는 초기화 함수입니다. 이 함수가 인수에 할당되지 않으면 초기 state는 initialArg로 설정됩니다. 할당되었다면 초기 state는 init(initialArg)를 호출한 결과가 할당됩니다.

 

설명하기 어려워 그냥 리액트의 공식문서에 있는 내용 갖다썼다... 샘플코드로 한번 보도록 하자..

 

 

useReducer 훅 샘플코드

 

App.jsx

import { useReducer } from "react";
import { ReducerExam } from "./components/ReducerExam";

const App = () => {
  return (
    <>
      <div className="App">
        <ReducerExam />
      </div>
    </>
  );
};

export default App;

 

 

ReducerExam.jsx

import React, { useReducer } from "react";
import { reducer } from "../js/reducer.js";

export const ReducerExam = () => {
  const [state, dispatch] = useReducer(reducer, 0);

  const onChangeState = (type) => {
    dispatch({
      type: type,
      data: 1,
    });
  };

  return (
    <>
      <div>
        <h1>{state}</h1>
        <button onClick={() => onChangeState("plus")}>+</button>
        <button onClick={() => onChangeState("minus")}>-</button>
      </div>
    </>
  );
};

 

 

reducer.js

const reducer = (state, action) => {
  switch (action.type) {
    case "plus":
      return state + action.data;
    case "minus":
      return state - action.data;
    default:
      return state;
  }
};

export { reducer };

 

 

결과

0

 

 

 

여기서 하나 짚고 넘어갈 내용이 있는데, 리듀서 함수는 순수함수이기 때문에 직접 state를 참조하지 않도록

코드를 작성하는 게 좋다. (외부 영향을 받으면 안됨)

※ input과 ouput으로만 동작하는 게 좋음..

 

 

 

어떤 경우에 useReducer 훅을 사용할까? (useState와의 차이점)

 

  1. useState:
    • 간단한 상태 관리: 상태가 간단하고 단순한 경우에 주로 사용됩니다.
    • 단일 값 또는 객체의 간단한 속성 변경: 상태가 간단하고, 변경되는 속성이 하나이거나 몇 개인 경우에
      적합합니다.
    • 컴포넌트 내부에서만 사용하는 상태: 해당 상태를 다른 컴포넌트와 공유할 필요가 없고, 컴포넌트 내부에서만
      사용하는 경우에 사용됩니다.
  2. useReducer:
    • 복잡한 상태 관리: 상태가 복잡하고 여러 개의 관련된 속성을 포함하거나, 상태 간의 관계가 복잡한 경우에
      사용됩니다.
    • 다양한 액션에 대한 상태 변화 처리: 다양한 액션에 대한 상태 변화를 하나의 reducer 함수에서
      처리할 수 있습니다.
    • 상태 업데이트 로직이 복잡한 경우: 상태 업데이트 로직이 복잡하거나 중복이 많은 경우에 useReducer를
      사용하여 코드를 간결하고 유지보수 가능하게 할 수 있습니다.

 

위가 useState와 useReducer의 차이점인데... 요약하자면

 

useState: 간단한 상태관리, 컴포넌트 내부에서만 사용하는 상태

useReducer: 복잡한 상태관리, 복잡한 상태관리 로직을 외부 모듈로 빼고 싶을때, 다양한 액션 상태 변화가 있을 때..

 

위와 같이 정리 할 수 있을 거 같다...

 

 

 

728x90
profile

개발공작소

@모찌바라기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!