Script

Redux part-4 / Payload / Ducks 패턴 본문

항해99/4주차 주특기 숙련

Redux part-4 / Payload / Ducks 패턴

scripter. 2022. 8. 1. 13:54

1.Payload

Payload란?

 

만약 전에 만든 카운터 기능에서 +1, -1처럼 정해진 것이 아니라 

증가시킬 숫자를 사용자가 직접 정할 수 있게 하려면 어떻게 해야 할까.

 

여태까지 우리는 몇을 더할지 임의적으로  정한 후에 리듀서에게 더하라는 명령만 내렸다.

지금부터는 "더하라"가 아닌 "N을 더하라" 처럼 목적어가 있는 명령을 내릴 것이다.

목적어도 액션객체에 담아서 같이 보내줘야 할 것이다.

 

여기서 이 목적어에 해당하는 것이 바로 payload인 것이다.

// payload가 추가된 액션객체

{type: "ADD_NUMBER", payload: 10} // type뿐만 아니라 payload라는 key와 value를 같이 담는다.

 

payload 사용하기

 

순서는 다음과 같다.

  1. 사용자가 입력한 값을 받을 input 구현하기
  2. Action Creator 작성하기
  3. 리듀서 작성하기
  4. 구현된 기능 테스트 하기

counter 모듈의 Action Creator

// src/redux/modules/counter.js

// Action Value
const ADD_NUMBER = "ADD_NUMBER";

// Action Creator
export const addNumber = (payload) => {
  return {
    type: ADD_NUMBER,
    payload //payload: payload와 같다
  };
};

// Initial State

// Reducer

// export default reducer

지금까지 작성한 Action Creator와 조금 차이가 있다. payload가 필요한 Action Creator에서는 함수를 선언할 때 매개변수 자리에 paylaod를 넣어줘야 한다. 왜냐하면 Action Creator를 사용하는 컴포넌트에서 리듀서로 보내고자 하는 payload를 인자로 넣어줘야 하기 때문.

인자로 payload를 넣어줌으로써 Action Creator가 액션객체를 생성할때 payload를 같이 담아 생성하는 원리이다.

 

counter 모듈의 Initial State, Reducer, 내보내기(export default)

// Initial State
const initialState = {
  number: 0,
};

// 리듀서

const counter = (state = initialState, action) => {
  switch (action.type) {
    case ADD_NUMBER:
      return {
		// state.number (기존의 nubmer)에 action.paylaod(유저가 더하길 원하는 값)을 더한다.
        number: state.number + action.payload,
      };
    default:
      return state;
  }
};

사용자가 컴포넌트에서 Action Creator로 payload를 담아 보내는 것은 액션객체에 담겨지고, 그렇게 담겨진 것은

리듀서에서 action.payload에서 꺼내 사용할 수 있다. 그래서 그것을 이용하여 기존의 값에 더해줌으로써 기능이 완성된다

 

Action Creator를 import하고, payload를 담아 dispatch

import React from "react";
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";

// 4. Action Creator를 import 합니다.
import { addNumber } from "./redux/modules/counter";

const App = () => {
	// 1. dispatch를 사용하기 위해 선언해줍니다.
  const dispatch = useDispatch();
  const [number, setNumber] = useState(0);
  const globalNumber = useSelector((state) => state.counter.number);

  const onChangeHandler = (evnet) => {
    const { value } = evnet.target;
    setNumber(+value);
  };

	// 2. 더하기 버튼을 눌렀을 때 실행할 이벤트핸들러를 만들어줍니다.
  const onClickAddNumberHandler = () => {
		// 5. Action creator를 dispatch 해주고, 그때 Action creator의 인자에 number를 넣어줍니다.
    dispatch(addNumber(number));
  };

  return (
    <div>
      <div>{globalNumber}</div>
      <input type="number" onChange={onChangeHandler} />
			{/* 3. 더하기 버튼 이벤트핸들러를 연결해줍니다. */}
      <button onClick={onClickAddNumberHandler}>더하기</button>
      <button>빼기</button>
    </div>
  );
};

export default App;

천천히 보면서 흐름을 파악해보자.

 

왼쪽:App.js 오른쪽:counter.js

 

2.Ducks 패턴

 

Ducks 패턴이란?

 

리덕스의 구성요소를 만들 때 우리 모두가 지켜야할 양식이다.

  1. Reducer 함수를 export default 한다.
  2. Action creator 함수들을 export 한다.
  3. Action type은 app/reducer/ACTION_TYPE 형태로 작성한다.

(외부 라이브러리로서 사용될 경우 또는 외부 라이브러리가 필요로 할 경우에는 UPPER_SNAKE_CASE 로만 작성해도 괜찮다.)

 

그래서 모듈 파일 1개에 Action Type, Action Creator, Reducer가 모두 존재하는 작성방식인 것이다.

 

정리

  • 리듀서로 보내는 액션객체에 어떤 정보를 같이 담아보내고자 한다면 payload를 이용한다.
  • payload는 Action Creator를 생성할 때 매개변수에 자리에서 받을 준비를 하고, 반환하는 액션객체에 payload라는 key와 받은 매개변수를 value로 하여 구현한다.
  • 리듀서에서 payload를 사용하고자 할 때는 action.payload로 사용할 수 있다.
  • ES6에서 객체를 생성할 때 key와 value가 같으면 축약해서 작성할 수 있다.
  • Ducks 패턴은 리덕스의 구성요소를 만들 때 우리가 지키기로 협의한 양식이다.
Comments