useReducer

seul_velog·2022년 4월 7일
0

React

목록 보기
7/11
post-thumbnail

useReducer

  • 상태를 관리하는 방법으로 useState 말고도 useReducer 가 있다. useState 의 확장판이라고 생각하자.
  • 컴포넌트의 상태 업데이트 로직을 컴포넌트에서 분리시킬 수 있다.
  • 상태 업데이트 로직을 컴포넌트 바깥에서 작성할 수도 있으며, 다른 파일에 작성 후 불러와서 사용할 수도 있다.

✍️ 다음과 같은 상황에서 사용하면 좋다.

  • 다수의 하윗값을 포함하는 복잡한 정적 로직을 만드는 경우
  • 다음 state가 이전 state에 의존적인 경우




reducer() 함수 알기

reducer()현재 상태액션 객체를 파라미터로 받아와서 새로운 상태를 반환해주는 함수이다.

function reducer(state, action) {
  // 새로운 상태를 만드는 로직
  // const nextState = ...
  return nextState;
}
  • reducer() 에서 반환하는 상태는 곧 컴포넌트가 지닐 새로운 상태가 된다.
  • action업데이트를 위한 정보를 가지고 있다. 주로 type 값을 지닌 객체 형태로 사용한다.




useReducer의 구조

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

📌 state
앞으로 컴포넌트에서 사용할 수 있는 상태를 가르킨다.

📌 dispatch
액션을 발생시키는 함수이다.

📌 useReducer 의 파라미터

  • reducer (첫 번째 파라미터) : reducer 함수
    → state 를 변경하는 로직이 담겨 있는 함수

  • initialState(두 번째 파라미터) : 초기 상태





useReducer를 사용해서 상태를 변경하기

✍️ 예제를 통해 알아보자

click 버튼을 누르면 count (state) 값이 증가하도록 만들기

import { useReducer } from 'react';

export default function reducerTest() {
  const reducer = (state, action) => { // 2)
    if (action.type === 'PLUS') {
      return {
        count: state.count + 1,
      };
    }
    return state;
  };

  // dispatch => action 객체를 넣어서 실행
  // action => 객체이고 필수 프로퍼티로 type을 가진다.

  const [state, dispatch] = useReducer(reducer, { count: 0 }); // 1)
  return (
    <div>
      <p>You clicked {state.count} times</p> 
      <button onClick={click}> Click me</button>
    </div>
  );

  function click() {
    dispatch({ type: 'PLUS' }); // 3)
  }
}


1) useReducer Hook

 const [state, dispatch] = useReducer(reducer, { count: 0 }); // 1)

  <p>You clicked {state.count} times</p> // 1-1)
  • useReducer() 함수를 사용해서 첫 번째 인자로 reducer 함수를, 두 번째 인자로 state의 초기값이 들어가도록 만든다.
    여기서는 우리가 상상하는 초기값 {count:0} 을 넣는다.

  • useState 에서는 state와 setState를 사용했다. useState Hook 으로부터 나오는 return은 배열을 반환하고 첫 번째는 현재의 state를, 두 번째 인자는 state를 변경하는 것을 의미했다.

  • useReducer 반환 배열

    • 1 번째 원소 : 마찬가지로 state를 의미한다. 따라서 1-1) state에 있는 카운트를 꺼내서 사용할 수 있다.

    • 2 번째 원소 : state를 변경할 수 있는 dispatch함수가 반환된다.
      ( reducer 에서는 useState의 'setState' 와 같이 사용하지 않고 'dispatch' 라는 이름으로 사용한다. )


2) reducer()

  const reducer = (state, action) => { // 2)
    if (action.type === 'PLUS') {
      return {
        count: state.count + 1,
      };
    }
    return state;
  };
  • reducer() : state 를 변경하는 로직이 담겨 있는 함수

  • reducer 함수의 파라미터

    • 첫 번째 파라미터 : 이전상태(previous state) 를 의미한다.

    • 두 번째 파라미터 : action 이라고 하는 객체가 들어온다. 즉 state를 조작하려는 객체를 의미한다.

  • 결과적으로 새로운 상태(newState) 를 리턴한다.

  • 즉 이전state와 변경하려는 action 객체가 들어오면 새로운 상태를 만들어서 리턴해주면 된다고 이해할 수 있다.
    ❓action 객체는 어떻게 들어올까? → dispatch 를 통해서 전달한다. ▼


3) dispatch

 const reducer = (state, action) => { // 2)
    if (action.type === 'PLUS') { // 3-1)
      return {
        count: state.count + 1,
      };
    }
    return state; // 3-2)
  };

  function click() {
    dispatch({ type: 'PLUS' }); // 3)
  }
  • 현재상태를 변경하는 dispatch 함수를 호출한다. 즉, dispatch()에 action 객체를 넣어서 실행시킨다.
  • action은 보통 객체이며 필수 프로퍼티로 type을 가진다.
  • 여기서 타입은 2) 의 state에 count 를 +1 증가시키는 액션타입을 담아서 보내준다. 임의의 이름을 붙일 수 있다.
  • 3-1) 과 같이 action.type 으로 접근가능하다.
  • 새로운 객체를 리턴하며 if 문 조건에 해당되지 않으면 3-2 처럼 그냥 변경없이 state를 return한다.



useState vs useReducer

🤔 그렇다면 둘 중 어떤 것을 사용하면 좋을까?

useState

  • 컴포넌트에서 관리하는 값이 딱 하나이고, 그 값이 단순한 숫자나 문자열 또는 boolean 값이라면 useState 로 관리하는게 편하다.

useReducer

  • 컴포넌트에서 관리하는 값이 여러 개로 상태의 구조가 복잡해진다면 useReducer 로 관리하는 것이 편할 수 있다.
    → 즉 다수의 하윗값을 포함하는 복잡한 state일 경우 사용하면 좋다.

  • 다음 state가 이전 state에 의존적인 경우에 사용하면 좋다.
    → 이전 state를 가지고 있다가 action과 함께 조합해서 새로운 state를 만들어 내기 때문이다.😀




React Hooks API

profile
기억보단 기록을 ✨

0개의 댓글