[React.js] Redux (2)
์นดํ
๊ณ ๋ฆฌ : Development
ํ๊ทธ: development · react · Redux · State · Action · Reducer · Dispatch · ActionCreator · AsyncAction · Middleware · Store · StoreCreator · StoreEnhancer · redux-devTools
ํ๊ทธ: development · react · Redux · State · Action · Reducer · Dispatch · ActionCreator · AsyncAction · Middleware · Store · StoreCreator · StoreEnhancer · redux-devTools
๐ย redux ์๋๋ฐฉ์
- ์ฐ๋ฆฌ๋ ๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ํ(๋ฐ์ดํฐ)๋ฅผ Store๋ผ๋ ๋จ์ผ ์์น์ ์ ์ฅ.ย ํ๋ฐํธ์๋์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ก ์ ์ฅ
- 3๊ฐ์ง ์ฃผ์ ๋ถ๋ถ
- Store - ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ
- Reducer - ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐ, ์ ๋ฐ์ดํธ ๋ฐ ์ญ์ ํ๋ ๊ธฐ๋ฅ(์ฌ์ฉ ๋ฐฉ๋ฒ) โข
- Actions - ์ํํ ์์ (๋ฌด์์ ํด์ผ ํ๋์ง)์ ์ ์
- Reducer ๊ธฐ๋ฅ์ ํตํด์๋ง Store ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค..
- ํ ์ผ ๋ชฉ๋ก ๋ง๋ค๊ธฐ
- Action - ADD_TASK
- Reducer - perform how to add task in the store
๐ย Redux ๊ตฌํ์ ์ํ 4๋จ๊ณ:
- Designing the store - Store ๊ฐ์ฒด์ ๋ชจ์ต
- List actions - ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ํ
- ๋ฆฌ๋์ ๋ง๋ค๊ธฐ - ํด๋น ์์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ ์ ์ํ๋ ๊ธฐ๋ฅ
- ๋ฆฌ๋์ค ์คํ ์ด ์์ฑ
๐ปCreating Reducer function:
- ๊ฐ์๊ธฐ๋ ๋ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋ ์์ ํจ์์ ๋๋ค.ย ์ฒซ ๋ฒ์งธ๋ ์ด๊ธฐ ๋๋ ํ์ฌ ์ํ์ด๊ณ ๋ ๋ฒ์งธ๋ ์์ ๊ฐ์ฒด
- ์ด ํจ์ ๋ด์์ If..else๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ Switch ์ผ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ ํ์ ์๋ณํ ์ ์์ต๋๋ค.
let id = 0;
export default function reducer(state = [], action) {
switch (action.type) {
case ADD_TASK:
return [
...state,
{
id: ++id,
task: action.payload.task,
completed: false,
},
];
case REMOVE_TASK:
return state.filter((task) => task.id !== action.payload.id);
case TASK_COMPLETED:
return state.map((task) =>
task.id === action.payload.id
? {
...task,
completed: true,
}
: task
);
default:
return state;
}
}
๐ย redux ์คํ ์ด ๊ตฌ์ฑ
- ๋ฆฌ๋์ค ์คํ ์ด๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ๋ฆฌ๋์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ createStore๋ผ๋ ํจ์๊ฐ ์๊ณ ๋ฃจํธ ๋ฆฌ๋์๋ฅผ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌํ๊ธฐ๋ง ํ๋ฉด ๋.
import { legacy_createStore as createStore } from "redux";
import reducer from "./tasks";
const store = createStore(reducer);
export default store;
๐ง๐ปโ๐ปย Store์์ ๋ฐ์ดํฐ ์ ๋ฌ
- ์ด๋ค ์ก์ ์ ๋ฐ์กํ๋ ค๋ฉด store.dispatch ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๊ณ type ์์ฑ(์ก์ ์ด๋ฆ)๊ณผ ํ์ด๋ก๋ ์์ฑ(์ก์ ๊ณผ ๊ด๋ จ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์์)์ ๊ฐ์ง ์ก์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํด์ผ ๋.
store.dispatch({ type: "ADD_TASK", payload: { task: "Add new task" } });
๐๊ตฌ๋ ๋ฐ ํํด ๋ฐฉ๋ฒ
- YouTube์์ ๊ตฌ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํจ์ ๋ฐ๋ผ store.subscribe ๋ฉ์๋๋ ์คํ ์ด ๊ฐ์ฒด์ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ๋ ์๋ฆผ์ ๋ฐ๋ ๋ฐ์๋ ์ฌ์ฉ
store.subscribe(() => {
console.log("Updated", store.getState());
});
- ์ด ์ฝ๋ฐฑ ํจ์๋ redux ์คํ ์ด์ ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์์ ์คํ.
- ์ด์ ์ด ๊ตฌ๋ ๋ฐฉ๋ฒ์ ์ค์งํ๋ ค๋ฉด ๊ตฌ๋ ์ทจ์๋ฅผ ์ฌ์ฉํด์ผํจ.
const unsubscribe = store.subscribe(() => {
console.log("Updated", store.getState());
});
unsubscribe();
๐redux-devTools ๊ตฌ์ฑ ๋ฐฉ๋ฒ
npm i redux-devtools-extension ๋๋ yarn add redux-devtools-extension
- configureStore ํ์ผ์์ ์ดย ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์น ํ๊ณ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ devToolsEnhancer๋ฅผ ๊ฐ์ ธ์ด.
import { legacy_createStore as createStore } from "redux";
import { devToolsEnhancer } from "redux-devtools-extension";
import reducer from "./tasks";
const store = createStore(reducer, devToolsEnhancer({ trace: true }));
export default store;
- ๋ํ ์ด ํ์ฅ์ผ๋ก ์ถ์ ์ ์ํํ ์ ์์ผ๋ฉฐ ์ด ํ์ฅ์์ ๋ก๊ทธ ํ์ผ์ ๊ฐ์ ธ์ค๊ณ ๋ด๋ณด๋ผ ์๋ ์์.