[React JS] Hooks - useReducer

 

useReducer

리액트에서 컴포넌트의 상태를 관리하기 위해 useState를 가장 많이 사용하였다.

하지만, useState 말고도 useReducer를 사용하여 상태관리가 가능하다.

useReducer는 useState버다 더 다양한 컴포넌트 상황에 따라 다양한 상태를 다른 값으로 업데이트하고 싶을 때 자주 사용한다.

즉, 더 복잡한 상태 관리가 필요한 경우 useReducer를 사용할 수 있다.

 

 

▶ useReducer는 한 컴포넌트 내에서 state를 업데이트하는 로직 부분을 그 컴포넌트로부터 분리시키는 것을 가능하게 해준다.

 -> state 업데이트 로직을 분리하여 컴포넌트의 외부에 작성하는 것을 가능하게 한다.

 -> 코드의 최적화 이루게 한다.

< useState 사용하여 state 업데이트 >

import {useState} from 'react';

const Counter = () => {
  const [counterNum, setCounterNum] = useState(0);
  
  const addCounterClick = () => {
    setCounterNum(counterNum + 1);
  };

  const subCounterClick = () => {
    setCounterNum(counterNum - 1);
  };
  
  return(
    <div>
      <h1>현재 Counter 값: {counterNum}</h1>
      <button onClick={addCounterClick}>+1</button>
      <button onClick={subCounterClick}-1</button>
    </div>
  );
}

export default Counter;

 

< useReducer 사용해 state 업데이트 >

import {useReducer} from 'react';

function reducer(state, action){
  switch(action.type){
    case 'INCREMENT':
      return { value: state.value + 1 };
    case 'DECREMENT':
      return { value: state.value - 1 };
    default:
      return state;
    }
 }
 
 const Counter = () => {
   const [state, dispatch] = useReducer(reducer, {value: 0});
   
   return(
     <div>
       <h2>현재 counter 값: {state.value}</h2>
       <button onClick={() => dispatch({type: 'INCREMENT'})}>+1</button>
       <button onClick={() => dispatch({type: 'DECREMENT'})}>-1</button>
     </div>
   );
 };
 
 export default Counter;

useReducer 사용하면 컴포넌트 외부에 state 업데이트 로직이 존재한다.

 

 

useState useReducer
- 관리해야 할 state가 1개일 때
- state가 단순한 값일 경우(숫자, 문자열, boolean 등)
- 관리해야 할 state가 여러 개일 경우
- state 구조가 복잡해질 경우

 

 

useReducer 사용법

1. useReducer 작성

const [state, dispatch] = useReducer(reducer, initialState);
//const [counter, dispatch] = useReducer(reducer, 0);
  • state: 컴포넌트에서 사용할 수 있는 상태를 가르킴
  • dispatch: action을 발생시키는 함수. 첫 번째 인자인 reducer 함수를 실행시킨다. 컴포넌트 내에서 state의 업데이트를 일으키기 위해 사용하는 함수.
  • reducer: 컴포넌트 외부에서 state를 업데이트 하는 함수. 현재 state와 action 객체를 인자로 받아 기존의 state를 대체하여 새로운 state를 반환한다.
  • initialState: 초기 state

 

 

2. action

: 업데이트를 위한 정보를 가지고 있다.

dispatch의 인자가 되고, reducer 함수의 두 번째 인자인 action에 할당된다.

 

: 주로 type이라는 값을 가진 객체 형태로 사용된다.

 

dispatch({type: "DECREMENT" })

위의 {type: "DECREMENT"}와 같이 action을 작성할 수 있다.

 

const App = () => {
  const [counter, dispatch] = useReducer(reducer, {num: 0});
  
  return(
    <div>
      <h2>현재 Counter 값: {counter.num}</h2>
      <button onClick={() => dispatch({type: "DECREMENT"})}-</button>
    </div>
  );
}

 

 

3. dispatch 함수

: reducer 함수를 실행시킨다.

dispatch 함수의 인자로 업데이트를 위한 정보를 가진 action을 이용하여 컴포넌트 내에서 state의 업데이트를 일으키기 위해 사용한다.

 

=> dispatch 함수의 인자 action은 reducer 함수의 두 번째 인자인 action에 할당된다.

const App = () => {
  const [counter, dispatch] = useReducer(reducer, {num: 0});
  
  return(
    <div>
      <h2>현재 Counter 값: {counter.num}</h2>
      <button onClick={() => dispatch({type: "DECREMENT"})}-1</button>
    </div>
  );
}

 

 

 

4. reducer 함수

: state를 어떻게 바꿀지 정하는 코드가 작성된다.

: dispatch 함수에 의해 실행되고, 컴포넌트 외부에서 state를 업데이트하는 로직 담당

: 함수의 인자로 state와 action을 받게 된다.

 -> state와 action을 활용해 새로운 state를 반환한다.

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

 

 

 

반응형