[React] useReducer

HR·2022년 6월 23일
1

React

목록 보기
4/5

useReducer

  • useState의 대체자. useState보다 복잡한 상태를 다룰 때 사용.
  • (state, action) => newState의 형태로 reducer를 받고, dispatch 메소드와 현재 state를 반환한다.

useState를 사용한 Count

import "./styles.css";
import { useState } from "react";
export default function App() {
  const [count, setCount] = useState(0);

  function down() {
    setCount((count) => count - 1);
  }

  function reset() {
    setCount(0);
  }

  function up() {
    setCount((count) => count + 1);
  }

  return (
    <div className="App">
      <input type="button" value="-" onClick={down} />
      <input type="button" value="0" onClick={reset} />
      <input type="button" value="+" onClick={up} />
      <span>{count}</span>
    </div>
  );
}
  • useState에서 state는 장부, event는 고객으로 비유를 들 수 있다.

  • 현재 코드는 고객이 직접 장부를 수정하고 있는 상황(down, up 함수 등을 사용해서)이라고 볼 수 있다. 하지만 고객이 늘어난다면, 수많은 고객들이 그 장부를 작성하면 복잡성이 늘어나면서 관리에 어려움을 겪을 수 있다.

useReducer를 사용한 Count

  • useReducer를 사용하면 더이상 고객이 장부를 직접 수정하지 않는다. 고객은 단순히 주문을 말하고(출금, 입금 등) 창구직원이 그 주문을 받게 된다. 그리고 다시 회계직원에게 넘기고, 회계직원은 들어온 정보를 확인해서 새로운 장부를 작성하게 된다.

  • 여기서 주문은 action, 창구직원은 dispatch, 회계직원은 reducer로 비유할 수 있다.

생활코딩유튜브(4:57) 참고해서 그린 그림

import "./styles.css";
import { useReducer } from "react";
export default function App() {
  function countReducer(oldCount, action) {
    if (action === "Up") {
      return oldCount + 1;
    } else if (action === "Down") {
      return oldCount - 1;
    } else if (action === "Reset") {
      return 0;
    }
  }

  // countDispatch: 창구직원 - dispatch
  // countReducer: 회계직원 - reducer
  // useReducer의 두 번째 파라미터로 초기값이 들어감
  const [count, countDispatch] = useReducer(countReducer, 0);

  function down() {
    // action을 dispatch에게 전달
    countDispatch("Down");
  }

  function reset() {
    countDispatch("Reset");
  }

  function up() {
    countDispatch("Up");
  }

  return (
    <div className="App">
      <input type="button" value="-" onClick={down} />
      <input type="button" value="0" onClick={reset} />
      <input type="button" value="+" onClick={up} />
      <span>{count}</span>
    </div>
  );
}

input만큼 증가시키기

import "./styles.css";
import { useState, useReducer } from "react";
export default function App() {
  const [number, setNumber] = useState(1);

  function countReducer(oldCount, action) {
    if (action.type === "Up") {
      return oldCount + action.number;
    } else if (action.type === "Down") {
      return oldCount - action.number;
    } else if (action.type === "Reset") {
      return 0;
    }
  }

  const [count, countDispatch] = useReducer(countReducer, 0);

  function down() {
    countDispatch({type: "Down", number});
  }

  function reset() {
    countDispatch({type: "Reset", number});
  }

  function up() {
    countDispatch({type: "Up", number});
  }

  function changeNumber(event) {
    setNumber(Number(event.target.value));
  }

  return (
    <div className="App">
      <input type="button" value="-" onClick={down} />
      <input type="button" value="0" onClick={reset} />
      <input type="button" value="+" onClick={up} />
      <input type="number" value={number} onChange={changeNumber} />
      <span>{count}</span>
    </div>
  );
}
  • 사용자가 입력한 만큼 값을 count 해야 하기 때문에, number state를 하나 만들고, dispatch에 그 값을 같이 전달한다. 보통 action을 전달할 때 type과 payload를 프로퍼티명으로 사용해서 객체 형식으로 전달한다고 한다.

참고

생활코딩 유튜브

profile
Hello World :D

0개의 댓글