๐Ÿš€ Boilerplate ์ฝ”๋“œ๋ž€?

์ž„๊ด‘ํ›ˆยท2025๋…„ 2์›” 3์ผ

Boilerplate ์ฝ”๋“œ๋ž€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
ํŠนํžˆ, Redux๋Š” ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ๋งŽ์€ Boilerplate ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ •์ด ๋ณต์žกํ•˜๊ณ  ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์กด์žฌํ•œ๋‹ค.

โœ… Redux์—์„œ์˜ Boilerplate ์ฝ”๋“œ ์˜ˆ์ œ

Redux๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ตœ์†Œํ•œ Action, Reducer, Store๋ฅผ ์„ค์ •ํ•ด์•ผ ํ•˜๊ณ , ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ dispatch(action)์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.
์ด ๊ณผ์ •์„ ๊ฑฐ์น˜๋‹ค ๋ณด๋ฉด ๋ฐ˜๋ณต์ ์ด๊ณ  ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„์ง„๋‹ค.

1๏ธโƒฃ Action ์ •์˜ (์•ก์…˜ ํƒ€์ž…๊ณผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜ ์ž‘์„ฑ)

// actions.js
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

const increment = () => ({ type: INCREMENT });
const decrement = () => ({ type: DECREMENT });

โœ… ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ ์•ก์…˜ ํƒ€์ž…๊ณผ ์•ก์…˜ ์ƒ์„ฑ ํ•จ์ˆ˜(action creator)๋ฅผ ์ •์˜ํ•ด์•ผ ํ•จ.

2๏ธโƒฃ Reducer ์ž‘์„ฑ

// reducer.js
const initialState = { count: 0 };

function counterReducer(state = initialState, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

โœ… reducer๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์—ญํ• ์„ ํ•˜์ง€๋งŒ, switch-case ๋ฌธ์ด ๊ธธ์–ด์ง€๊ณ  ๋ณต์žกํ•ด์ง€๋Š” ๋ฌธ์ œ๊ฐ€ ์กด์žฌ.

3๏ธโƒฃ Store ์ƒ์„ฑ

// store.js
import { createStore } from 'redux';
import counterReducer from './reducer';

const store = createStore(counterReducer);

export default store;

โœ… ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” store๋„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•จ.

4๏ธโƒฃ ์ปดํฌ๋„ŒํŠธ์—์„œ Redux ์‚ฌ์šฉ

// Counter.js
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';

function Counter() {
  const count = useSelector((state) => state.count);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => dispatch(increment())}>+</button>
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}
โœ… ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด useSelector(), ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด dispatch(action)์„ ์จ์•ผ ํ•ด์„œ ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง.

๐Ÿ”ฅ Zustand์—์„œ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉด? (Boilerplate ์ฝ”๋“œ ์ œ๊ฑฐ)

Redux์˜ ๋ณต์žกํ•œ ์„ค์ • ์—†์ด, ๋‹จ ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋งŒ์œผ๋กœ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ ๊ฐ€๋Šฅ!

import { create } from 'zustand';

// Zustand ์Šคํ† ์–ด ์ƒ์„ฑ (๋‹จ 1์ค„)
const useCounterStore = create((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
  decrease: () => set((state) => ({ count: state.count - 1 })),
}));

// ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ
function Counter() {
  const { count, increase, decrease } = useCounterStore();

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increase}>+</button>
      <button onClick={decrease}>-</button>
    </div>
  );
}

โœ… Redux์— ๋น„ํ•ด ์ฝ”๋“œ๊ฐ€ ์—„์ฒญ ์งง์•„์ง€๊ณ , ๊ตฌ์กฐ๊ฐ€ ์ง๊ด€์ !

๐ŸŽฏ Boilerplate ์ฝ”๋“œ์˜ ํ•ต์‹ฌ ๋ฌธ์ œ์ 

  1. ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๊ณ  ๋ฐ˜๋ณต๋˜๋Š” ๋ถ€๋ถ„์ด ๋งŽ๋‹ค.
    • Redux๋Š” action, reducer, store, dispatch ๋“ฑ์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์„ค์ •ํ•ด์•ผ ํ•ด์„œ ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง.
  2. ์„ค์ • ๊ณผ์ •์ด ๋ณต์žกํ•˜๋‹ค.
    • ์ž‘์€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋”๋ผ๋„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•จ.
  3. ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋–จ์–ด์ง„๋‹ค.
    • ํŠนํžˆ switch-case ๋ฌธ์ด ๋งŽ์•„์ง€๋ฉด, ๋กœ์ง์„ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง.
  4. ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ์ด ๋งŽ์•„์ง„๋‹ค.
    • actions.js, reducers.js, store.js ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•ด์•ผ ํ•จ.

โœ… ๊ฒฐ๋ก : Redux๋Š” ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ์„ค์ •์ด ๋ฒˆ๊ฑฐ๋กญ๊ณ  Boilerplate ์ฝ”๋“œ๊ฐ€ ๋งŽ์•„ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค. ๋ฐ˜๋ฉด, Zustand๋Š” ๋” ๊ฐ„๊ฒฐํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๋‹ค! ๐Ÿš€

profile
๋‚˜, ๊ฐ€๋Šฅ

0๊ฐœ์˜ ๋Œ“๊ธ€