useReducer 1

dev_sang·2022년 3월 22일
0
post-thumbnail

출처 : 유튜브 별코딩 https://www.youtube.com/watch?v=tdORpiegLg0

useReducer란?

  • useState처럼 state를 생성, 관리할 수 있게 해주는 도구
  • 여러개의 하위값을 포함하는 복잡한 State를 써야 할 때 useState대신 useReducer를 쓴다.

useReducer 의 구성 요소

  • Reducer
  • Dispatch
  • Action

reducer는 dispatch에 담긴 action의 내용에 따라 state를 업데이트해주는 역할을 한다.

예를 들어, A가 은행(reducer)에서 예금 거래내역(state)를 업데이트하려고 한다면, 은행에 요구(dispatch)를 하는데 그 요구의 내용(action)이 "만원을 입금해주세요."인 것이다. 즉 은행(reducer)이 철수의 요구의 내용(dispacth의 action)에 따라 거래내역(state)를 업데이트 해준다.

Dispatch함수의 인자에 Action넣어서 Reducer에게 보낸다 → Reducer가 받아서 Action내용 대로 State를 업데이트한다.

입금 출금 로직 만들어보기

1. useReducer와 useState를 import 해온다.

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

2. action의 type을 지정해준다.

const ACTION_TYPES = {
  DEPOSIT: "deposit",
  WITHDRAW: "withdraw"
};

3. State 초기값 지정

useState의 초기값(0), 그리고 useReducer에 reducer와 초기값(0)을 넣는다. number state는 input값의 상태값이다.

function App() {
  const [money, dispatch] = useReducer(reducer, 0);
  const [number, setNumber] = useState(0);

4. onClick -> dispatch

버튼 클릭 시 reducer로 보낼 요구사항 (dispatch안의 action)을 넣는다.

  return (
    <div className="App">
      <h1>잔고: {money}</h1>

      <input
        type="number"
        value={number}
        onChange={(e) => {
          setNumber(parseInt(e.target.value));
        }}
        step="1000"
      />

      <button
        onClick={() => {
          dispatch({ type: ACTION_TYPES.DEPOSIT, payload: number });
        }}
      >
        {" "}
        예금{" "}
      </button>
      <button
        onClick={() => {
          dispatch({ type: ACTION_TYPES.WITHDRAW, payload: number });
        }}
      >
        {" "}
        출금{" "}
      </button>
    </div>
  );

5. App 함수 위에 reducer를 생성

switch문으로 action type에 따라 실행할 내용을 구분한다.
deposit일 경우 기존 state에 payload에 담긴 값을 더하고, withdraw의 경우 기존 state에 payload에 담긴 값을 뺀다.

const reducer = (state, action) => {
  switch (action.type) {
    case ACTION_TYPES.DEPOSIT:
      return state + action.payload;
    case ACTION_TYPES.WITHDRAW:
      return state - action.payload;
    default:
      return state;
  }
};

전체 코드

import React, { useReducer, useState } from "react";
import "./styles.css";

const ACTION_TYPES = {
  DEPOSIT: "deposit",
  WITHDRAW: "withdraw"
};

const reducer = (state, action) => {
  switch (action.type) {
    case ACTION_TYPES.DEPOSIT:
      return state + action.payload;
    case ACTION_TYPES.WITHDRAW:
      return state - action.payload;
    default:
      return state;
  }
};

function App() {
  const [money, dispatch] = useReducer(reducer, 0);
  const [number, setNumber] = useState(0);
  return (
    <div className="App">
      <h1>잔고: {money}</h1>

      <input
        type="number"
        value={number}
        onChange={(e) => {
          setNumber(parseInt(e.target.value));
        }}
        step="1000"
      />

      <button
        onClick={() => {
          dispatch({ type: ACTION_TYPES.DEPOSIT, payload: number });
        }}
      >
        {" "}
        예금{" "}
      </button>
      <button
        onClick={() => {
          dispatch({ type: ACTION_TYPES.WITHDRAW, payload: number });
        }}
      >
        {" "}
        출금{" "}
      </button>
    </div>
  );
}

export default App;

profile
There is no reason for not trying.

0개의 댓글