๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽฎ ํ”„๋กœ๊ทธ๋ž˜๋ฐ/๐Ÿ‘ฉ‍๐Ÿ’ป ๊ฐœ๋ฐœ ๊ณต๋ถ€

[React] Redux ๊ฐœ๋… ๋ฐ ์—ญํ• , ํŒŒ์ผ ๊ตฌ์กฐ ๋””๋ ‰ํ† ๋ง

by xxilliant 2025. 2. 27.
728x90
๋ฐ˜์‘ํ˜•

๊ฐœ๋ฐœ์„ ์ฒ˜์Œ ์ง„ํ–‰ํ•  ๋•Œ๋Š” ๋ฆฌ๋•์Šค ๋‚ด์šฉ์„ ํ•œ ํŒŒ์ผ์—๋‹ค๊ฐ€ ๋ชจ์•„๋‘๋‹ค๊ฐ€,

์ธํ„ด ํ•˜๋ฉด์„œ ๋””๋ ‰ํ† ๋ง ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์› ์—ˆ๋Š”๋ฐ ๋˜ ์จ๋จน์„ ์ผ์ด ์ƒ๊ฒจ ๊ธฐ๋กํ•ด๋‘”๋‹ค.


 

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 ๋ณ€์ˆ˜ ์ž‘๋™ ๋ฐฉ์‹

  1. ์ปดํฌ๋„ŒํŠธ์—์„œ dispatch(setCategories([...]) ์‹คํ–‰
    • ์ƒˆ๋กœ์šด ์นดํ…Œ๊ณ ๋ฆฌ ๋ฆฌ์ŠคํŠธ๋ฅผ Redux์— ์ „๋‹ฌ
  2. Reducer๊ฐ€ setCategories ์•ก์…˜์„ ๊ฐ์ง€ํ•˜๊ณ  state.categoryList ๋ณ€๊ฒฝ
    • categoryList๊ฐ€ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ์—…๋ฐ์ดํŠธ๋จ
  3. ์ปดํฌ๋„ŒํŠธ์—์„œ 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 ์•ก์…˜์„ ํ˜ธ์ถœํ•˜๊ณ  ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.
โœ… ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์นดํ…Œ๊ณ ๋ฆฌ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค.

 

 

728x90
๋ฐ˜์‘ํ˜•