JS' 공부흔적

[React] useReducer에 대하여 본문

React

[React] useReducer에 대하여

이준수 2022. 11. 30. 18:30

useReducer는 reducer를 사용하여 다양한 상태를 다른 값으로 업데이트할 때 사용하는 Hook이다. 여기서 reducer란, 현재 상태 state와 업데이트를 위해 필요한 정보가 담겨있는 Action 값을 파라미터로 받아서 state를 변경하는 함수이다. Redux에서도 사용하는 개념이니 아래 글을 참고해도 좋을 것 같다.

 

[Redux] Vanilla Redux의 기본 개념

Redux는 Javascript의 상태 관리 라이브러리이다. 보통 React와 함께 많이 사용되지만, Augular, jQuery, vanilla JavaScript 등 여러 framework에서 사용이 가능하다. Redux에 기본적인 개념 및 용어를 알아보자. npm i

2junsu.tistory.com

참고로 Redux에서 사용하는 액션은 객체여야하며 어떤 액션인지를 알려주는 type이 필수적이지만, useReducer에서는 꼭 객체일 필요는 없고, type을 지니고 있지 않아도 된다. 그럼 useReducer의 기본적인 사용법을 알아보자.

const [status, dispatch] = useReducer(reducer, initialState);

 

useReducer는 위와 같이 선언한다. state는 현재 가리키고 있는 상태이고, dispatch는 액션을 발생시키는 함수이다. 즉, reducer에 액션을 보내는 역할을 한다. reducer는 위에서 말했듯이 액션을 받아서 state를 변경하는 함수이고, initialState는 초기 상태를 나타낸다.

 

이를 가지고 input 창의 값을 변경하는 간단한 예제를 만들어보자. 아래 코드는 name과 nickname을 입력하는 2개의 input이 주어지고 각 input에 name을 부여하여 이 name에 따라 state값을 변경하는 코드이다.

import React, { useEffect, useReducer } from "react";

interface StateType {
  name: string;
  nickname: string;
}

const initialState: StateType = {
  name: "",
  nickname: "",
};

const reducer = (state: StateType, action: EventTarget & HTMLInputElement) => {
  return {
    ...state,
    [action.name]: action.value,
  };
};

const App = () => {
  const [status, dispatch] = useReducer(reducer, initialState);
  const { name, nickname } = status;

  useEffect(() => {
    console.log("name: " + name);
    console.log("nickname: " + nickname);
  }, [name, nickname]);

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    dispatch(e.target);
  };

  return (
    <div>
      <div>
        <span>name&nbsp;</span>
        <input name="name" value={name} onChange={onChange} />
      </div>
      <div>
        <span>nickname&nbsp;</span>
        <input name="nickname" value={nickname} onChange={onChange} />
      </div>
    </div>
  );
};

export default App;

initialState를 name과 nickname 모두 empty string으로 초기화하고, input 값이 바뀔 때마다 onChange 함수에서 dispatch를 통해 액션값 e.target을 reducer로 보낸다. reducer 함수에서는 받은 action, 즉 e.target의 name을 가지고 업데이트할 상태를 찾아내 값을 변경해준다. 이때 reducer 함수에서 상태를 업데이트할 때는 반드시 불변성을 지켜야 한다. 불변성을 지킨다는 것은 데이터의 원본이 훼손되는 것을 막는다는 뜻이다. 따라서 기존의 상태를 수정하는 것이 아닌 항상 새로운 상태를 반환해야한다는 것을 의미한다. 또한, 위에서 볼 수 있듯이 컴포넌트 밖에 reducer를 선언했는데 여기서 알 수 있는 점은 useReducer를 사용하면 업데이트 로직을 컴포넌트 밖으로 뺄 수 있다는 것이다. 이는 useReducer의 가장 큰 장점인데, 컴포넌트를 분리할 때 업데이트 로직을 같이 분리하지 않아도 되기 때문이다. 마지막으로 상태값이 변경될 때마다 console.log를 통해 원하는 대로 동작하는지를 확인해봤다. 실행 결과는 아래와 같다.

728x90
반응형