κ°λ°μ μ²μ μ§νν λλ 리λμ€ λ΄μ©μ ν νμΌμλ€κ° λͺ¨μλλ€κ°,
μΈν΄ νλ©΄μ λλ ν λ§ νλ λ°©λ²μ λ°°μ μλλ° λ μ¨λ¨Ήμ μΌμ΄ μ겨 κΈ°λ‘ν΄λλ€.
Reduxλ μ ν리μΌμ΄μ μ μνλ₯Ό νκ³³μμ κ΄λ¦¬νλ λΌμ΄λΈλ¬λ¦¬μ΄λ€.
μ¬λ¬ μ»΄ν¬λνΈμμ κ°μ λ°μ΄ν°λ₯Ό 곡μ ν λ μ μ©νλ€.
1οΈβ£ Redux νμΌ κ΅¬μ‘° (in React typescript)
/redux
/actions # μ‘μ
μ μ (μ΄λ²€νΈ λ°μ μ νμν λ°μ΄ν° μ μ)
categoryActions.ts
/reducers # 리λμ μ μ (μνκ° μ΄λ»κ² λ³κ²½λ μ§ κ²°μ )
categoryReducer.ts
store.ts # μ€ν μ΄ μ€μ (μ 체 μν κ΄λ¦¬)
κ° νμΌμ Reduxμ ν΅μ¬ μμμΈ μ‘μ (Actions), 리λμ(Reducers), μ€ν μ΄(Store)λ₯Ό λ΄λΉνλ€.
2οΈβ£ νμΌλ³ μν
π redux/actions/categoryActions.ts
Reduxμμ μνλ₯Ό λ³κ²½νλ €λ©΄ "μ‘μ (Action)"μ΄ νμνλ€.
μ‘μ μ μ΄λ€ μνλ₯Ό λ³κ²½ν κ²μΈμ§ μλ €μ£Όλ "λ©μμ§" μν μ νλ€.
import { createAction } from "@reduxjs/toolkit";
export const setCategories = createAction<string[]>("SET_CATEGORIES");
β
setCategoriesλ μΉ΄ν
κ³ λ¦¬ 리μ€νΈλ₯Ό λ³κ²½νλ μ‘μ
μ μμ±νλ ν¨μμ΄λ€.
β
"SET_CATEGORIES"λΌλ νμ
μ κ°μ§ μ‘μ
μ λ§λ€κ³ , string[] λ°μ΄ν°λ₯Ό μ λ¬ν μ μλ€.
π redux/reducers/categoryReducer.ts
Reducerλ μ‘μ μ λ°μμ μνλ₯Ό μ€μ λ‘ λ³κ²½νλ μν μ νλ€.
import { createReducer } from "@reduxjs/toolkit";
import { setCategories } from "../actions/categoryActions";
interface CategoryState {
categoryList: string[];
}
const initialState: CategoryState = {
categoryList: [],
};
const categoryReducer = createReducer(initialState, (builder) => {
builder.addCase(setCategories, (state, action) => {
state.categoryList = action.payload;
});
});
export default categoryReducer;
β
initialState: μ΄κΈ° μν κ° (categoryList λ°°μ΄)
β
createReducer: setCategories μ‘μ
μ΄ νΈμΆλλ©΄ categoryListλ₯Ό λ³κ²½
β
action.payload: μ‘μ
μ΄ μ λ¬ν λ°μ΄ν° (string[])
π store.ts
μ€ν μ΄(Store)λ Reduxμ μ€μ μ μ₯μμ΄λ€. λͺ¨λ μνμ 리λμλ₯Ό λͺ¨μμ κ΄λ¦¬νλ€.
import { configureStore } from "@reduxjs/toolkit";
import categoryReducer from "./reducers/categoryReducer";
const store = configureStore({
reducer: {
category: categoryReducer, // μν μ΄λ¦μ categoryλ‘ μ€μ
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
β
configureStore: μ¬λ¬ 리λμλ₯Ό ν©μ³μ Redux μ€ν μ΄λ₯Ό μμ±
β
RootState: Redux μνμ νμ
μ μ
β
store.dispatch: μ‘μ
μ Reduxμ μ λ¬νλ ν¨μ
3οΈβ£ Redux λ³μ μλ λ°©μ
- μ»΄ν¬λνΈμμ dispatch(setCategories([...]) μ€ν
- μλ‘μ΄ μΉ΄ν κ³ λ¦¬ 리μ€νΈλ₯Ό Reduxμ μ λ¬
- Reducerκ° setCategories μ‘μ
μ κ°μ§νκ³ state.categoryList λ³κ²½
- categoryListκ° μλ‘μ΄ λ°μ΄ν°λ‘ μ λ°μ΄νΈλ¨
- μ»΄ν¬λνΈμμ useSelector(state => state.category.categoryList)λ‘ μν κ°μ Έμ€κΈ°
- λ³κ²½λ μνλ₯Ό μ»΄ν¬λνΈμμ μ¬μ© κ°λ₯
4οΈβ£ Redux λ³μλ₯Ό μ¬μ©νλ λ°©λ²
Reduxμ μνλ₯Ό React μ»΄ν¬λνΈμμ μ¬μ©νλ €λ©΄ useSelectorμuseDispatchλ₯Ό νμ©ν΄μΌ νλ€.
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { setCategories } from "../redux/actions/categoryActions";
import { RootState } from "./redux/store";
const CategoryComponent: React.FC = () => {
const dispatch = useDispatch();
const categoryList = useSelector((state: RootState) => state.category.categoryList);
const updateCategories = () => {
dispatch(setCategories(["Food", "Electronics", "Clothing"]));
};
return (
<div>
<h1>Categories</h1>
<ul>
{categoryList.map((category, index) => (
<li key={index}>{category}</li>
))}
</ul>
<button onClick={updateCategories}>Update Categories</button>
</div>
);
};
export default CategoryComponent;
β
useSelectorλ₯Ό μ¬μ©ν΄ Redux μν(categoryList)λ₯Ό κ°μ Έμ¨λ€.
β
useDispatchλ₯Ό μ¬μ©ν΄ setCategories μ‘μ
μ νΈμΆνκ³ μνλ₯Ό μ
λ°μ΄νΈνλ€.
β
λ²νΌμ ν΄λ¦νλ©΄ μΉ΄ν
κ³ λ¦¬ 리μ€νΈκ° λ³κ²½λλ€.