(1) Action Creator 란?
만약에 우리가 액션객체의 value를 변경할 일이 생긴다면 어떨까요? PLUS_ONE , MINUS_ONE 이라는 value 대신 이 액션객체가 counter 모듈안에 있다는 것을 강조하기 위해서 counter/PLUS_ONE, counter/MINUS_ONE 이라는 value로 바꾸길 각각 바꾸길 원한다면 아래 코드에서 4군데를 변경해줘야 할 것 입니다. 근데 또 만약에 그게 4군데가 아니라 프로젝트 규모가 굉장히 커서 100군데라면 어떨까요? 곤란하겠죠?
(2) Action Creator 만들기만약 PLUS_ONE 이라는 액션 객체를 만드는 함수를 만든다면 아래와 같이 만들 수 있습니다.
그리고 우리는 이것을 Action Creator라고 부릅니다. 해석 그대로 액션을 만드는 생성자 인 것이죠.그래서 앞으로는 위 코드처럼 직접 하드코딩을 하는 것이 아니라, 액션객체를 한 곳에서 관리할 수 있도록 “함수"와 액션 value를 상수로 만들어보겠습니다.
// src/redux/modules/counter.jsconst PLUS_ONE = "PLUS_ONE";// value는 상수로 생성// 액션객체를 반환하는 함수 생성// export 가 붙는 이유는 plusOne()는 밖으로 나가서 사용될 예정이기 때문입니다.export const plusOne = () => {
return {
type: PLUS_ONE,// type에는 위에서 만든 상수로 사용 (vscode에서 자동완성 지원)
};
};
이렇게 액션의 value는 상수로 따로 만들어주고, 그리고 그것을 이용해서 액션객체를 반환하는 함수를 작성합니다. 그리고 이것을 실제로 리듀서와 컴포넌트에서는 아래와 같이 작성합니다.
리듀서 전체 코드를 볼까요?
모듈에 initialState와 리듀서밖에 없었지만 액션의 value와 Action Creator가 추가되었습니다.
// src/modules/counter.js// 추가된 코드 👇 - 액션 value를 상수들로 만들어 줍니다. 보통 이렇게 한곳에 모여있습니다.const PLUS_ONE = "PLUS_ONE";
const MINUS_ONE = "MINUS_ONE";
// 추가된 코드 👇 - Action Creator를 만들어 줍니다.export const plusOne = () => {
return {
type: PLUS_ONE,
};
};
export const minusOne = () => {
return {
type: MINUS_ONE,
};
};
// 초기 상태값const initialState = {
number: 0,
};
// 리듀서const counter = (state = initialState, action) => {
switch (action.type) {
case PLUS_ONE:// case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다.return {
number: state.number + 1,
};
case MINUS_ONE:// case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다.return {
number: state.number - 1,
};
default:
return state;
}
};
export default counter;
(3) Action Creator 사용하기사용하는 방법은 아래순서로 진행합니다.
하나씩 코드로 보겠습니다. 우선 우리가 사용할 Action creator를 import 해야 합니다.
즉 Action creator는 태생적으로 counter.js 밖에서 사용될 함수들이었습니다. 그래서 생성할때부터 앞에 export 를 붙여준 것이었죠.
그리고 dispatch()안에 있던 액션객체를 import 한 Action Creator들로 변경해줍니다. 이렇게 하면 수정이 모두 끝났습니다.
우리가 생성한 Action Creator를 컴포넌트에서 어떻게 사용하는지 알아보겠습니다.
// src/App.jsimport React from "react";
import { useDispatch, useSelector } from "react-redux";
// 사용할 Action creator를 import 합니다.import { minusOne, plusOne } from "./redux/modules/counter";
const App = () => {
const dispatch = useDispatch();
const number = useSelector((state) => state.counter.number);
return (
<div>
{number}
<button
onClick={() => {
dispatch(plusOne()); // 액션객체를 Action creator로 변경합니다.
}}
>
+ 1
</button>
{/* 빼기 버튼 추가 */}
<button
onClick={() => {
dispatch(minusOne()); // 액션객체를 Action creator로 변경합니다.
}}
>
- 1
</button>
</div>
);
};
export default App;