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