1. External Store

  • ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ

  • Layered Architecture

  • Flux Architecture

  • useReducer

  • useCallback

๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ(Seperation of Concerns, SoC)

  • ํ”„๋กœ๊ทธ๋žจ์„ ๊ด€์‹ฌ์‚ฌ์— ๋”ฐ๋ผ ๋ชจ๋“ˆํ™” ํ•˜๋Š” ๊ฒƒ

  • ์ •๋ณด๋ฅผ ์ž˜ ์ •์˜๋œ ์ธํ„ฐํŽ˜์ด์Šค๊ธฐ ์žˆ๋Š” ๋ถ€๋ถ„์•ˆ์— ์บก์Аํ™” ์‹œํ‚ค๋ฉด์„œ ๋‹ฌ์„ฑ

  • ์ฝ”๋“œ์˜ ๋‹จ์ˆœํ™” ๋ฐ ์œ ์ง€๋ณด์ˆ˜์— ๋„์›€

  • ๋‹ค๋ฅธ ๋ถ€๋ถ„์˜ ์„ธ์„ธํ•œ ์‚ฌํ•ญ์„ ๋ชจ๋ฅด๋”๋ผ๋„ ๊ด€์‹ฌ์‚ฌ์˜ ์ฝ”๋“œ ๋ถ€๋ถ„์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Œ

  • ์ถ”์ƒํ™”์˜ ์ผ์ข…

Layered Architecture

  • ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ์˜ ๊ตฌํ˜„

  • ๊ฐ ๊ณ„์ธต์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ ํŠน์ • ์—ญํ• ๊ณผ ๊ด€์‹ฌ์‚ฌ๋ณ„๋กœ ๊ตฌ๋ถ„

  • UI๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„/ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„/ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ถ€๋ถ„

  • Input/ Process/ Output

  • MVC : Controller / Model / View

Flux ์•„ํ‚คํ…์ฒ˜

  • MVC๋Š” ์–‘๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ ์  ๋” ๋ณต์žกํ•ด์ง

  • Flux ์•„ํ‚คํ…์ฒ˜๋Š” ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ์•„ํ‚คํ…์ฒ˜

  • Action -> Dispatcher -> Store -> View์˜ ๋‹จ๋ฐฉํ–ฅ ์•„ํ‚คํ…์ฒ˜

    • ์‚ฌ์šฉ์ž์˜ action์ด ๋ฐœ์ƒํ•˜๋ฉด dispatcher๊ฐ€ ์—ฌ๋Ÿฌ store๋“ค์— action์„ ์ „๋‹ฌํ•˜๊ณ  store์—์„œ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด view์— ๋ฐ˜์˜๋จ

  • Redux๋Š” ๋‹จ์ผ Store๋ฅผ ์‚ฌ์šฉํ•ด Action -> Store -> View์˜ ๋‹จ๋ฐฉํ–ฅ ์•„ํ‚คํ…์ณ๋ฅผ ๊ฐ€์ง

    • action์ด ๋ฐœ์ƒํ•˜๋ฉด reducer๋ฅผ ํ†ตํ•ด state๋ฅผ ๋ณ€๊ฒฝ

External Store

  • Store๊ฐ€ ๋ฆฌ์•กํŠธ ๋ฐ–์— ์žˆ์Œ

๋‚ด๊ฐ€ ์ดํ•ดํ•œ external store์˜ ์ปจ์…‰

  • ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜๋ฉด ์žฌ๋ Œ๋”๋ง์„ ํ•œ๋‹ค

  • ๊ทธ๋ ‡๋‹ค๋ฉด ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฐ”๊พธ๊ณ ์ž ํ•˜๋Š” ๊ฐ’์„ useState๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ์›ํ•˜๋Š” ํƒ€์ด๋ฐ์— ์žฌ๋ Œ๋”๋ง๋งŒ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ๋‹ค

์ด๊ฑธ ์ด์šฉํ•ด์„œ

  • useForceUpdate ํ›…์„ ๋งŒ๋“ค์–ด ์•ˆ์—์„œ state๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ

  • ์ด ํ›…์€ state๋ฅผ ์ƒˆ ๊ฐ์ฒด(์˜๋ฏธ์žˆ๋Š” ๊ฐ’์€ ์•„๋‹ˆ๋‹ค)๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ด

  • ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด state๊ฐ€ ๋ณ€๊ฒฝ๋จ

  • ์ปดํฌ๋„ŒํŠธ์•ˆ์— ๊ด€๋ฆฌํ•˜๊ณ  ์‹ถ์€ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ณ  useForceUpdate๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด

  • ์ด ๊ฐ’์ด state๋กœ ๊ด€๋ฆฌ๋˜์ง€ ์•Š์•„๋„ ์žฌ๋ Œ๋”๋ง ๊ฐ€๋Šฅํ•ด์ง

์ด๋ฅผ ํ†ตํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ UI๊ตฌํ˜„์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค -> ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ

useReducer

const [<์ƒํƒœ ๊ฐ์ฒด>, <dispatch ํ•จ์ˆ˜>] = useReducer(<reducer ํ•จ์ˆ˜>, <์ดˆ๊ธฐ ์ƒํƒœ>, <์ดˆ๊ธฐ ํ•จ์ˆ˜>)
  • reducer ํ•จ์ˆ˜ : state์™€ action์„ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด state๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜

  • dispatch ํ•จ์ˆ˜ : ์ƒํƒœ ๋ณ€๊ฒฝ์„ ์ผ์œผํ‚ค๊ธฐ ์œ„ํ•ด action์„ ์ธ์ž๋กœ ๋ฐ›์•„ reducer์— ๋„˜๊ธฐ๋Š” ํ•จ์ˆ˜

  • action ๊ฐ์ฒด : ์–ด๋–ค ํ–‰๋™์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” type ์†์„ฑ๊ณผ ๊ทธ์— ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด

  • ์ฆ‰, dispatch์— action์„ ์ฃผ๋ฉด reducer๊ฐ€ ๊ทธ์— ๋งž๊ฒŒ state๋ฅผ ๋ณ€๊ฒฝํ•ด์คŒ

import React, { useReducer } from "react";

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      <h2>{state.count}</h2>
      <button onClick={() => dispatch({ type: "INCREMENT", step: 1 })}>
        ์ฆ๊ฐ€
      </button>
      <button onClick={() => dispatch({ type: "DECREMENT", step: 1 })}>
        ๊ฐ์†Œ
      </button>
    </>
  );
}

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case "INCREMENT":
      return { count: state.count + action.step };
    case "DECREMENT":
      return { count: state.count - action.step };
    default:
      throw new Error("Unsupported action type:", action.type);
  }
}

useCallback

  • ํ•จ์ˆ˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” hook

  • ์ฒซ๋ฒˆ์งธ ์ธ์ž๋กœ ๋„˜์–ด์˜จ ํ•จ์ˆ˜๋ฅผ ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ๋„˜์–ด์˜จ ๋ฐฐ์—ด์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๊นŒ์ง€ ์ €์žฅํ•˜๊ณ  ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ

  • ์ปดํฌ๋„ŒํŠธ์•ˆ์— ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ useCallback์œผ๋กœ ๋„˜๊ธฐ๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žฌ๋ Œ๋”๋ง๋˜๋„ ์ƒˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ธฐ์กดํ•จ์ˆ˜๋ฅผ ๊ณ„์†ํ•ด์„œ ๋ฐ˜ํ™˜

  • ๋ฐฐ์—ด์— ๋„ฃ์€ ๊ฐ’์ด ๋ฐ”๋€Œ๋ฉด ์ƒˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ฆ

const add = useCallback(() => x + y, [x, y]);

Last updated