Action creater
(1) Why we have to use Action creater?
a.만약에 우리가 액션객체의 value를 변경할 일이 생긴다면 어떨까요? PLUS_ONE , MINUS_ONE 이라는 value 대신 이 액션객체가 counter 모듈안에 있다는 것을 강조하기 위해서 counter/PLUS_ONE, counter/MINUS_ONE 이라는 value로 바꾸길 각각 바꾸길 원한다면 아래 코드에서 4군데를 변경해줘야 할 것 입니다.
근데 또 만약에 그게 4군데가 아니라 프로젝트 규모가 굉장히 커서 100군데라면 어떨까요? 곤란하겠죠?
우리가 만든 Action Creator가 만약 100군데에서 쓰이고 있는 상태에서 혹여나 그것을 바꾸어야 하는 상황이 오더라도 단 한번의 수정으로 100군데에 모든 수정사항을 반영할 수 있습니다.
*4군데의 종류
// src/App.js
dispatch({ type: "PLUS_ONE" }); // counter/PLUS_ONE로 변경
dispatch({ type: "MINUS_ONE" }); // counter/MINUS_ONE로 변경
// src/modules/counter.js
case "PLUS_ONE": // counter/PLUS_ONE로 변경
case "MINUS_ONE": // counter/MINUS_ONE로 변경
// src/App.js
import React from "react";
import { useDispatch, useSelector } from "react-redux";
const App = () => {
const dispatch = useDispatch();
const number = useSelector((state) => state.counter.number);
return (
<div>
{number}
<button
onClick={() => {
dispatch({ type: "PLUS_ONE" }); // counter/PLUS_ONE로 변경
}}
>
+ 1
</button>
<button
onClick={() => {
// 액션객체 디스패치
dispatch({ type: "MINUS_ONE" }); // counter/MINUS_ONE로 변경
}}
>
- 1
</button>
</div>
);
};
export default App;
// src/modules/counter.js
// 초기 상태값
const initialState = {
number: 0,
};
// 리듀서
const counter = (state = initialState, action) => {
switch (action.type) {
case "PLUS_ONE": // counter/PLUS_ONE로 변경
return {
number: state.number + 1,
};
// action.type이 MINUS_ONE 일 때 새로운 state 반환
case "MINUS_ONE": // counter/MINUS_ONE로 변경
return {
number: state.number - 1,
};
default:
return state;
}
};
// 모듈파일에서는 리듀서를 export default 한다.
export default counter;
b.액션객체의 type value를 상수로 만들어놓았기 때문에, 개발툴에서 자동완성등의 보조 기능을 지원받을 수 있습니다. 그래서 의도치 않은 휴먼에러(오타)를 없앨 수 있어요.
(2) Action Creator 만들기
그래서 앞으로는 액션객체를 한 곳에서 관리할 수 있도록 '함수'와 액션 value를 상수로 만들어보겠습니다.
만약 PLUS_ONE 이라는 액션 객체를 만드는 함수를 만든다면 아래와 같이 만들 수 있습니다.
그리고 우리는 이것을 Action Creator라고 부릅니다. 해석 그대로 액션객체를 만드는 생성자 인 것이죠.
// src/redux/modules/counter.js
const 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;
action creater를 사용하기전과 액션객체를 하드코딩했을때의 비교
// 하드코딩했을때의 예시
case "PLUS_ONE":
return {
// 기존 state에 있던 number에 +1을 더한다.
number: state.number + 1,
};
// 액션크리에이터를 사용했을때의 예시
case PLUS_ONE: // case에서도 문자열이 아닌, 위에서 선언한 상수를 넣어줍니다.
return {
number: state.number + 1,
};
분명 case PLUS_ONE이 아닌 case "PLUS_ONE"이었다. 즉, Action creater를 사용할때는 미리 정의해준 상수를 사용한 것이다.
(3) Action Creator 사용하기
우리가 생성한 Action Creator를 컴포넌트에서 어떻게 사용하는지 알아보겠습니다.
사용하는 방법은 아래순서로 진행합니다.
- export된 Action Creator import 하기
- dispatch()에 있던 액션객체를 지우고, Action creator 넣기
하나씩 코드로 보겠습니다. 우선 우리가 사용할 Action creator를 import 해야 합니다.
즉 Action creator는 태생적으로 counter.js 밖에서 사용될 함수들이었습니다. 그래서 생성할때부터 앞에 export 를 붙여준 것이었죠.
그리고 dispatch()안에 있던 액션객체를 import 한 Action Creator들로 변경해줍니다. 이렇게 하면 수정이 모두 끝났습니다.
// src/App.js
import 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;
action creater를 사용하기전과 액션객체를 하드코딩했을때의 비교
// 하드코딩했을떄의 예시
<button
onClick={() => {
dispatch({ type: "PLUS_ONE" });
}}
// 액션크리에이터를 사용했을때의 예시
<button
onClick={() => {
dispatch(plusOne()); // 액션객체를 Action creator로 변경합니다.
}}
Q. dispatch() 안에는 반드시 객체만 들어가야 한다고 알고 있는데, 어떻게 함수가 들어갈 수 있을까요?
A. {type: “PLUS_ONE”} === plusOne()는 같은 값입니다. 함수를 실행한 것은 함수의 return 값과 같습니다. 다시 말해,
const one = () => {return 1; } 로 함수를 만들었을 때 one() === 1 입니다.
최종정리
- 액션객체를 만드는 함수를 Action Creator(액션 크리에이터)라고 한다.
- Action Creator는 모듈 파일안에서 생성된다.
- 액션객체의 type value로 상수로 생성해서 관리한다.
- Action Creator를 사용하면, 여러가지 문제점을 해소할 수 있다.
'내일배움캠프[4기_Reac트랙] > [원격]React_숙련' 카테고리의 다른 글
React Router(1)[숙련_7] (0) | 2023.01.08 |
---|---|
Payload[숙련_6] (0) | 2022.12.22 |
Counter구현[숙련_4] (0) | 2022.12.18 |
모듈생성,스토어연결,useSelector[숙련_3] (0) | 2022.12.18 |
Redux start![숙련_2] (0) | 2022.12.18 |