aotoyae

[React] Redux(2) : action 객체에 payload 를 넘겨보자, Ducks 패턴 본문

React

[React] Redux(2) : action 객체에 payload 를 넘겨보자, Ducks 패턴

aotoyae 2024. 1. 25. 00:12

 

 

 

[React] Redux : useSelector, useDispatch, 중앙 데이터 관리

💡 리덕스를 활용해 보자~ props 를 넘겨주는 방식은 계속 지나쳐가는(props 를 넘겨주기만 하는) 컴포넌트가 생길 수 있다. 중앙 데이터 관리소 store 를 만들어서 데이터를 한번에 가져올 수 있도

aotoyae.tistory.com

이어서..

 

위 글에서 action 객체에 type 만 넘겨주고 있는데

만약 input 을 만들어서 숫자를 받고, 버튼 클릭시

그 숫자만큼 증가하거나 감소하게 만들고 싶다면?

 

💡 action 객체에 payload 를 추가한다.
action 객체는 action type 을 payload 만큼 처리하는 것이다.

payload 가 3이면, 3만큼을 plus

 

먼저 counter.js 로 가서 새 함수와 새 case 를 만든다.

const PLUS_ONE = "counter/PLUS_ONE";
const MINUS_ONE = "counter/MINUS_ONE";
const PLUS_N = "counter/PLUS_N";
const MINUS_N = "counter/MINUS_N";

export const plusOne = () => {
  return {
    type: PLUS_ONE,
  };
};

export const minusOne = () => {
  return {
    type: MINUS_ONE,
  };
};

export const plusN = (payload) => {
  return {
    type: PLUS_N,
    payload: payload, // 페이로드까지 받아온 새 객체
  };
};

export const minusN = (payload) => {
  return {
    type: MINUS_N,
    payload,
  };
};

const initialState = {
  number: 0,
};

const counter = (state = initialState, action) => {
  switch (action.type) {
    case PLUS_ONE:
      return { number: state.number + 1 };
    case MINUS_ONE:
      return { number: state.number - 1 };
    case PLUS_N:
      return { number: state.number + action.payload }; // 원래 숫자에 받아온 페이로드 더함
    case MINUS_N:
      return { number: state.number - action.payload };
    default:
      return state;
  }
};

export default counter;

 

App.js

import "./App.css";
import { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { plusN, minusN } from "./redux/modules/counter"; {/*import*/}

function App() {
  const [number, setNumber] = useState(0);

  const counter = useSelector((state) => {
    return state.counter;
  });

  const dispatch = useDispatch(); {/*얜 액션 객체를 store에 전달하는 애란걸 잊지 말자.*/}

  return (
    <>
      <div>현재 카운트 : {counter.number}</div>
      <div>
        <input
          type="number"
          value={number}
          onChange={(event) => { {/*인풋 값이 바뀌면 number 가 업데이트 된다.*/}
            const { value } = event.target; {/*구조분해할당, event.target 의 value 만 가져온다.*/}
            setNumber(+value); {/*value 가 지금 문자열이니, Number 로 변환*/}
          }}
        />
      </div>
      <button
        onClick={() => {
          dispatch(plusN(number)); {/*업데이트 된 넘버(페이로드)를 함수로 전달한다*/}
        }}
      >
        +
      </button>
      <button
        onClick={() => {
          dispatch(minusN(number));
        }}
      >
        -
      </button>
    </>
  );
}

export default App;

원하는 값을 더하거나 뺄 수 있게 됐다. 🥲

 

💡 Ducks 패턴

리덕스 모듈은 개발자마다 구성요소 방식이 제각각일 수 있다.

협업을 위해 이 방식을 패턴화해 작성하게 되었는데 그 패턴이 바로 Ducks 패턴!

 

Ducks 패턴은 아래 내용을 지켜 모듈을 작성하는 것

1. Reducer 함수를 export default 한다.

2. Action creator 함수들을 export 한다.

3. Action type 은 app / reducer / ACTION_TYPE 형태로 작성한다.

(외부 라이브러리로서 사용될 경우 or 외부 라이브러리가 필요할 경우,

UPPER_SNAKE_CASE 로만 작성해도 괜찮다.)

 

그래서 모듈 파일 1 개에 action type, action creator, reducer 가 모두 존재하는 작성 방식이다.

위 코드는 이를 지켜 작성되었다.