Unit3 - [React] ์‹ฌํ™” - 2

๊ฐ•์„ฑ์ผยท2023๋…„ 7์›” 20์ผ
0
post-thumbnail

โœ… TIL


React๋Š” ํ˜„์žฌ๋„ ๊ณ„์†ํ•ด์„œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜๊ณ  ์žˆ๋Š” ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

์ด๋ฒˆ์— React๊ฐ€ ๋ฒ„์ „ 18๋กœ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜๋ฉด์„œ ๋งŽ์€ ๋ถ€๋ถ„์ด ๋ฐ”๋€Œ์—ˆ๋Š”๋ฐ,
๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ณ€ํ™”๋Š” ์ฝ˜์†” ์ฐฝ์— ์ด์ „์— ๋ณด์ด์ง€ ์•Š๋˜ ๊ฒฝ๊ณ ๋ฌธ์ด ๋ณด์ธ๋‹ค๋Š” ์ ์ด๋‹ค.

ํ•ด๋‹น ๊ฒฝ๊ณ ๋ฌธ์€ ์ด์ œ React 18 ๋ฒ„์ „์€ ๋” ์ด์ƒ ReactDOM.render๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋‚ด์šฉ์ด๋‹ค.

๋ฌผ๋ก  ๋ฒ„์ „์ด 18๋ณด๋‹ค ๋‚ฎ์€ ์•ฑ์—์„œ๋Š” ํ•ด๋‹น ๊ฒฝ๊ณ ๋ฌธ์€ ๋ณด์ด์ง€ ์•Š๋Š”๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ณ„์†ํ•ด์„œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋˜๊ณ  ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ˆ๋งŒํผ ํ•ด๋‹น ์ด์Šˆ๋Š” ์•Œ์•„๋‘ฌ์•ผ ํ•  ๊ฒƒ์ด๋‹ค.

์–ธ์ œ๊นŒ์ง€ 18 ๋ฒ„์ „ ์ดํ•˜๋งŒ ์‚ฌ์šฉํ•  ์ผ์€ ์—†์„ ๊ฒƒ์ด๊ณ ,
18 ๋ฒ„์ „์„ ์“ฐ๋Š”๋ฐ๋„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ด์ „์˜ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

// React 18์ด์ „์˜ index.js

const rootElement = document.getElementById("root");
ReactDOM.render(<AppTest />, rootElement);
// ๋ฐ”๋€ index.js
import { createRoot } from "react-dom/client";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
    <App />
);


์ €๋Ÿฐ ๊ฒฝ๊ณ ๋ฌธ์ด ๋ณด์ด๋Š” ์ด์œ ๋Š” React 18์—์„œ๋Š” ์ด์ œ createRoot API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
React 18์—์„œ ์ƒ๊ธด ์ž๋™ ๋ฐฐ์นญ ๋˜ํ•œ ์ด createRoot API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ์ค‘ ์ฃผ๋ชฉํ•  ๋ถ€๋ถ„์€ Concurrent Feature์ด๋‹ค. ์ง€๊ธˆ๊นŒ์ง€๋Š” Concurrent Mode๋ผ๊ณ  ๋ช…๋ช…๋˜์—ˆ์ง€๋งŒ ์ด๋ฒˆ์— Concurrent Feature๋กœ ๋ฐ”๋€Œ๋ฉด์„œ ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์œผ๋กœ ๋“ค์–ด์˜ค๊ฒŒ ๋˜์—ˆ๋‹ค. ๊ทธ์ค‘์—๋Š” Suspense ๊ธฐ๋Šฅ์ด ์žˆ๋Š”๋ฐ, React 18 ๋ฒ„์ „๋ถ€ํ„ฐ๋Š” ์ด Suspense ๊ธฐ๋Šฅ์„ ์ด์šฉํ•ด ๋…๋ฆฝ์ ์œผ๋กœ ๋ Œ๋”๋ง์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค.



์ฝ”๋“œ ๋ถ„ํ• (Code Spliting)


React.lazy()์™€ Suspense ๊ธฐ๋Šฅ์„ ์•Œ๊ธฐ ์ „์—
์ฝ”๋“œ ๋ถ„ํ• (code spliting)์— ๋Œ€ํ•ด ์•Œ๋ฉด ์กฐ๊ธˆ ๋” ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค.

๋Œ€๋ถ€๋ถ„ React ์•ฑ๋“ค์€ Webpack, Rollup๊ณผ ๊ฐ™์€ ํˆด์„ ์‚ฌ์šฉํ•ด ๋ฒˆ๋“ค๋ง(Bundling)ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด HTML ์›น ํŽ˜์ด์ง€์— JavaScript๋ฅผ ์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋ฒˆ๋“ค๋œ ์•ฑ์€ ๋ชจ๋“  JavaScript๊ฐ€ ํ•œ ๊ณณ์— ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ํ˜ธ์ถœ ์ˆ˜๊ฐ€ ์ ์€ ๋งํฌ ํƒœ๊ทธ ํ•˜๋‚˜๋งŒ ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค. ๊ณผ๊ฑฐ์—๋Š” ์ด๋ ‡๊ฒŒ ํ•ด๋„ ๋ฌด๋ฆฌ๊ฐ€ ์—†์—ˆ๋‹ค. ๋ชจ๋˜ ์›น ์ด์ „์˜ ์›น JavaScript ์ฝ”๋“œ๋Š” ์ตœ์†Œํ•œ์˜ ์ˆ˜์ค€์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ๋Š” ๋ฒˆ๋“ค๋งํ•˜๊ฒŒ ๋˜๋ฉด ํŠน์ • ์ง€์ ์—์„œ ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ์ •๋„๊ฐ€ ๋Š๋ ค์ง€๊ฒŒ ๋˜์—ˆ๋‹ค.

๋ชจ๋˜ ์›น์œผ๋กœ ๋ฐœ์ „ํ•˜๋ฉด์„œ ์ ์  DOM์„ ๋‹ค๋ฃจ๋Š” ์ •๋„๊ฐ€ ์ •๊ตํ•ด์ง€๋ฉฐ,
JavaScript ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ๋ฐฉ๋Œ€ํ•ด์ง€๊ณ  ๋ฌด๊ฑฐ์›Œ์กŒ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

โ€œ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋Š ํŽ˜์ด์ง€์—์„œ ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ์ •๋„๊ฐ€ ๋Š๋ ค์กŒ๋Š”์ง€ ํŒŒ์•…ํ•ด์„œ ๋ฒˆ๋“ค์„ ๋‚˜๋ˆˆ ๋’ค์— ์ง€๊ธˆ ํ•„์š”ํ•œ ์ฝ”๋“œ๋งŒ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋‚˜์ค‘์— ํ•„์š”ํ•œ ์ฝ”๋“œ๋Š” ๋‚˜์ค‘์— ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์ง€ ์•Š์„๊นŒ??โ€

์ด๊ฒƒ์ด ์ฝ”๋“œ ๋ถ„ํ• ์˜ ํ•ต์‹ฌ ์•„์ด๋””์–ด์ด๋‹ค. ๋ฒˆ๋“ค์ด ๊ฑฐ๋Œ€ํ•ด์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ข‹์€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๋ฒˆ๋“ค์„ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ์ด๋‹ค. ์ฝ”๋“œ ๋ถ„ํ• ์€ ๋Ÿฐํƒ€์ž„ ์‹œ ์—ฌ๋Ÿฌ ๋ฒˆ๋“ค์„ ๋™์ ์œผ๋กœ ๋งŒ๋“ค๊ณ  ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒƒ์œผ๋กœ, Webpack, Rollup๊ณผ ๊ฐ™์€ ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์ฝ”๋“œ ๋ถ„ํ• ์„ ํ•˜๊ฒŒ ๋˜๋ฉด ์ง€๊ธˆ ๋‹น์žฅ ํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋”ฐ๋กœ ๋ถ„๋ฆฌ๋ฅผ ์‹œํ‚ค๊ณ , ๋‚˜์ค‘์— ํ•„์š”ํ•  ๋•Œ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•˜์—ฌ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์˜ ์•ฑ์ธ ๊ฒฝ์šฐ์—๋„ ํŽ˜์ด์ง€์˜ ๋กœ๋”ฉ ์†๋„๋ฅผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.


๋ฒˆ๋“ค ๋ถ„ํ•  ํ˜น์€ ์ค„์ด๋Š” ๋ฒ•

๋ฒˆ๋“ค๋ง ๋˜๋Š” ํŒŒ์ผ์—๋Š” ์•ฑ์„ ๋งŒ๋“ค๋ฉด์„œ npm์„ ํ†ตํ•ด ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ์„œ๋“œํŒŒํ‹ฐ(Third Party) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ํฌํ•จ์ด ๋œ๋‹ค. ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ฐœ์ธ ๊ฐœ๋ฐœ์ž๋‚˜ ํ”„๋กœ์ ํŠธ ํŒ€, ํ˜น์€ ์—…์ฒด ๋“ฑ์—์„œ ๊ฐœ๋ฐœํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์ฆ‰ ์ œ3์ž ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ ๋“ฑ์ด ์กด์žฌํ•˜๋ฉฐ, ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž˜ ์‚ฌ์šฉํ•˜๋ฉด ํŽธํ•˜๊ณ  ํšจ์œจ์ ์ธ ๊ฐœ๋ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ์˜ ์–‘์ด ๋งŽ๊ณ , ๋ฒˆ๋“ค๋ง ์‹œ ๋งŽ์€ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ ์ค‘์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ „๋ถ€๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋”ฐ๋กœ๋”ฐ๋กœ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋งŽ์€ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

/* ์ด๋ ‡๊ฒŒ lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ „์ฒด๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ ๊ทธ ์•ˆ์— ๋“ค์€ ๋ฉ”์„œ๋“œ๋ฅผ ๊บผ๋‚ด ์“ฐ๋Š” ๊ฒƒ์€ ๋น„ํšจ์œจ์ ์ด๋‹ค.*/
import _ from 'lodash';

...

_.find([]);

/* ์ด๋ ‡๊ฒŒ lodash์˜ ๋ฉ”์„œ๋“œ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ถˆ๋Ÿฌ์™€ ์“ฐ๋Š” ๊ฒƒ์ด ์•ฑ์˜ ์„ฑ๋Šฅ์— ๋” ์ข‹๋‹ค.*/
import find from 'lodash/find';

find([]);


ํ•ด๋‹น ์ฝ”๋“œ๋Š” lodash๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์˜ˆ์‹œ๋กœ ํ•˜๊ณ  ์žˆ๋‹ค. ์„น์…˜2์—์„œ underbar ๊ณผ์ œ๋ฅผ ํ–ˆ๋˜ ๊ฒƒ์„ ๊ธฐ์–ตํ•ด๋ณด์ž. ๊ทธ ๊ณผ์ œ๋Š” lodash ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋น„์Šทํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ œ์˜€๋‹ค. lodash๋Š” ๋ฐฐ์—ด, ์ˆซ์ž, ๊ฐ์ฒด, ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐ˜๋ณต์ ์ธ ์ž‘์—… ๊ฐ™์€ ๊ฒƒ์„ ํ•  ์‹œ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ข‹์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

lodash๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ํ•˜๋‚˜์˜ ํด๋”์™€ ๊ฐ™๊ณ , ๊ทธ ํด๋” ์•ˆ์—๋Š” ๊ฐœ๋ฐœ ์‹œ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์— ์“ฐ๊ธฐ ์ข‹์€ ๋ฉ”์„œ๋“œ๋“ค, ์ฆ‰ ํ•จ์ˆ˜ ์ฝ”๋“œ๋“ค์ด ๋“ค์–ด ์žˆ๋‹ค. ์ด ํ•จ์ˆ˜ ์ฝ”๋“œ๋“ค์˜ ์–‘์ด ์ƒ๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ „๋ถ€ ๊ฐ€์ ธ์˜ฌ ์‹œ, ์ •๋ง๋กœ ํ•„์š”ํ•œ ๊ฒƒ ํ•œ๋‘ ๊ฐœ๋งŒ ์“ฐ์ธ๋‹ค๋ฉด ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋ƒฅ ์“ฐ์ด์ง€ ์•Š๋Š” ์ฝ”๋“œ ๋ญ‰์น˜๋กœ ์•ฑ ๋‚ด๋ถ€์— ๋‚จ๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ์•ฑ์˜ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ฌ ์š”์ง€๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•„์š”ํ•œ ๊ฒƒ ํ•œ๋‘ ๊ฐœ๋งŒ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ์‹์œผ๋กœ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์ข‹๋‹ค.


React์—์„œ์˜ ์ฝ”๋“œ ๋ถ„ํ• 

React๋Š” SPA(Single-Page-Application)์ธ๋ฐ, ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊นŒ์ง€ ํ•œ ๋ฒˆ์— ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋•Œ๋ฌธ์— ์ฒซ ํ™”๋ฉด์ด ๋ Œ๋”๋ง ๋  ๋•Œ๊นŒ์ง€์˜ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. ๊ทธ๋ž˜์„œ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋‚˜์ค‘์— ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ๋ถ„ํ•  ๊ฐœ๋…์„ ๋„์ž…ํ–ˆ๋‹ค.

React์—์„œ ์ฝ”๋“œ ๋ถ„ํ• ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ dynamic import(๋™์  ๋ถˆ๋Ÿฌ์˜ค๊ธฐ)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ์ „๊นŒ์ง€๋Š” ์ฝ”๋“œ ํŒŒ์ผ์˜ ๊ฐ€์žฅ ์ตœ์ƒ์œ„์—์„œ import ์ง€์‹œ์ž๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค. ์ด๋ฅผ static import(์ •์  ๋ถˆ๋Ÿฌ์˜ค๊ธฐ)๋ผ๊ณ  ํ•œ๋‹ค.


Static Import

/* ๊ธฐ์กด์—๋Š” ํŒŒ์ผ์˜ ์ตœ์ƒ์œ„์—์„œ import ์ง€์‹œ์ž๋ฅผ ์ด์šฉํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์™”๋‹ค. */
import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  /* ๊ทธ๋ฆฌ๊ณ  ์ฝ”๋“œ ์ค‘๊ฐ„์—์„œ ๋ถˆ๋Ÿฌ์˜จ ํŒŒ์ผ์„ ์‚ฌ์šฉํ–ˆ๋‹ค. */
}


๊ธฐ์กด์—๋Š” ํ•ญ์ƒ import ๊ตฌ๋ฌธ์€ ๋ฌธ์„œ์˜ ์ƒ์œ„์— ์œ„์น˜ํ•ด์•ผ ํ–ˆ๊ณ , ๋ธ”๋ก๋ฌธ ์•ˆ์—์„œ๋Š” ์œ„์น˜ํ•  ์ˆ˜ ์—†๋Š” ์ œ์•ฝ ์‚ฌํ•ญ์ด ์žˆ์—ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฒˆ๋“ค๋ง ์‹œ ์ฝ”๋“œ ๊ตฌ์กฐ๋ฅผ ๋ถ„์„ํ•ด ๋ชจ๋“ˆ์„ ํ•œ ๋ฐ ๋ชจ์œผ๊ณ  ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ชจ๋“ˆ์€ ์ œ๊ฑฐํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…์„ ํ•˜๋Š”๋ฐ, ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ๊ฐ„๋‹จํ•˜๊ณ  ๊ณ ์ •์ด ๋˜์–ด ์žˆ์„ ๋•Œ์—์•ผ๋งŒ ์ด ์ž‘์—…์ด ๊ฐ€๋Šฅํ•ด์ง€๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ๋Š” ๊ตฌ๋ฌธ ๋ถ„์„ ๋ฐ ์ปดํŒŒ์ผํ•ด์•ผ ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ์˜ ์–‘์„
์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด dynamic import ๊ตฌ๋ฌธ์„ ์ง€์›ํ•œ๋‹ค.


Dynamic Import

form.addEventListener("submit", e => {
  e.preventDefault();
	/* ๋™์  ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋Š” ์ด๋Ÿฐ ์‹์œผ๋กœ ์ฝ”๋“œ์˜ ์ค‘๊ฐ„์— ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. */
  import('library.moduleA')
    .then(module => module.default)
    .then(someFunction())
    .catch(handleError());
});

const someFunction = () => {
    /* moduleA๋ฅผ ์—ฌ๊ธฐ์„œ ์‚ฌ์šฉํ•œ๋‹ค. */
}


์ด๋Ÿฐ ์‹์œผ๋กœ dynamic import๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ถˆ๋Ÿฌ์˜จ moduleA ๊ฐ€ ๋‹ค๋ฅธ ๊ณณ์—์„œ
์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๊ฐ€ form์„ ํ†ตํ•ด ์–‘์‹์„ ์ œ์ถœํ•œ ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

dynamic import๋Š” then ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ํ•„์š”ํ•œ ์ฝ”๋“œ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค.
๊ฐ€์ ธ์˜จ ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ชจ๋“  ํ˜ธ์ถœ์€ ํ•ด๋‹น ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒˆ๋“ค๋ง ์‹œ ๋ถ„ํ• ๋œ ์ฝ”๋“œ(์ฒญํฌ)๋ฅผ
์ง€์—ฐ ๋กœ๋”ฉ์‹œํ‚ค๊ฑฐ๋‚˜ ์š”์ฒญ ์‹œ์— ๋กœ๋”ฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด dynamic import๋Š” React.lazy ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.



React.lazy()์™€ Suspense


React.lazy()


React.lazy ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด dynamic import๋ฅผ ์‚ฌ์šฉํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

React๋Š” SPA(Single-Page-Application)์ด๋ฏ€๋กœ ํ•œ ๋ฒˆ์—
์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ปดํฌ๋„ŒํŠธ๊นŒ์ง€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค๊ณ  ์•ž์˜ ์ฑ•ํ„ฐ์—์„œ ํ•™์Šตํ–ˆ๋‹ค.

React๋Š” React.lazy๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋™์ ์œผ๋กœ import๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—
์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์ง€์—ฐ์‹œ๊ฐ„์„ ์–ด๋Š ์ •๋„ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

import Component from './Component';

/* React.lazy๋กœ dynamic import๋ฅผ ๊ฐ์‹ผ๋‹ค. */
const Component = React.lazy(() => import('./Component'));


์ด React.lazy๋กœ ๊ฐ์‹ผ ์ปดํฌ๋„ŒํŠธ๋Š” ๋‹จ๋…์œผ๋กœ ์“ฐ์ผ ์ˆ˜๋Š” ์—†๊ณ ,
React.suspense ์ปดํฌ๋„ŒํŠธ์˜ ํ•˜์œ„์—์„œ ๋ Œ๋”๋ง์„ ํ•ด์•ผ ํ•œ๋‹ค.



React.Suspense


Router๋กœ ๋ถ„๊ธฐ๊ฐ€ ๋‚˜๋ˆ„์–ด์ง„ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ lazy๋ฅผ ํ†ตํ•ด importํ•˜๋ฉด
ํ•ด๋‹น path๋กœ ์ด๋™ํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ฒŒ ๋˜๋Š”๋ฐ ์ด ๊ณผ์ •์—์„œ ๋กœ๋”ฉํ•˜๋Š” ์‹œ๊ฐ„์ด ์ƒ๊ธฐ๊ฒŒ ๋œ๋‹ค.

Suspense๋Š” ์•„์ง ๋ Œ๋”๋ง์ด ์ค€๋น„๋˜์ง€ ์•Š์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์„ ๋•Œ ๋กœ๋”ฉ ํ™”๋ฉด์„ ๋ณด์—ฌ์ฃผ๊ณ ,
๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋ฉด ๋ Œ๋”๋ง์ด ์ค€๋น„๋œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

/* suspense ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” import ํ•ด์™€์•ผ ํ•œ๋‹ค. */
import { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
			{/* ์ด๋Ÿฐ ์‹์œผ๋กœ React.lazy๋กœ ๊ฐ์‹ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ Suspense ์ปดํฌ๋„ŒํŠธ์˜ ํ•˜์œ„์— ๋ Œ๋”๋งํ•œ๋‹ค. */}
      <Suspense fallback={<div>Loading...</div>}>
				{/* Suspense ์ปดํฌ๋„ŒํŠธ ํ•˜์œ„์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ lazy ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. */}
        <OtherComponent />
				<AnotherComponent />
      </Suspense>
    </div>
  );
}


Supense ์ปดํฌ๋„ŒํŠธ์˜ fallback prop์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€
๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ๋กœ๋”ฉ ํ™”๋ฉด์œผ๋กœ ๋ณด์—ฌ์ค„ React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ›์•„๋“ค์ž…๋‹ˆ๋‹ค.

Suspense ์ปดํฌ๋„ŒํŠธ ํ•˜๋‚˜๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ lazy ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ค„ ์ˆ˜๋„ ์žˆ๋‹ค.


React.lazy์™€ Suspense์˜ ์ ์šฉ

์•ฑ์— ์ฝ”๋“œ ๋ถ„ํ• ์„ ๋„์ž…ํ•  ๊ณณ์„ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์€ ์‚ฌ์‹ค ๊นŒ๋‹ค๋กญ๊ธฐ ๋•Œ๋ฌธ์—, ์ค‘๊ฐ„์— ์ ์šฉ์‹œํ‚ค๋Š” ๊ฒƒ๋ณด๋‹ค๋Š”
์›น ํŽ˜์ด์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ง„์ž…ํ•˜๋Š” ๋‹จ๊ณ„ Route์— ์ด ๋‘ ๊ธฐ๋Šฅ์„ ์ ์šฉ์‹œํ‚ค๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

import { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);


๋ผ์šฐํ„ฐ์— Suspense๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ๊ฐ„๋‹จํ•œ ํŽธ์ด๋‹ค. ๋ผ์šฐํ„ฐ๊ฐ€ ๋ถ„๊ธฐ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ ์ปดํฌ๋„ŒํŠธ์— React.lazy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ importํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Route ์ปดํฌ๋„ŒํŠธ๋“ค์„ Suspense๋กœ ๊ฐ์‹ผ ํ›„ ๋กœ๋”ฉ ํ™”๋ฉด์œผ๋กœ ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ fallback ์†์„ฑ์œผ๋กœ ์„ค์ •ํ•ด ์ฃผ๋ฉด ๋œ๋‹ค. ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ๊ฐ„์ด ์ค„์–ด๋“œ๋Š” ๋ถ„๋ช…ํ•œ ์žฅ์ ์ด ์žˆ์œผ๋‚˜ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๋Š” ๊ณผ์ •๋งˆ๋‹ค ๋กœ๋”ฉ ํ™”๋ฉด์ด ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋น„์Šค์— ๋”ฐ๋ผ์„œ ์ ์šฉ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•ด์•ผ ํ•œ๋‹ค.



๐Ÿ’ฌ Sprint Review


์ด๋ฒˆ ๊ณผ์ œ๋Š” ์ด๋ฒˆ ์œ ๋‹›์—์„œ ๋ฐฐ์šด React Hooks๋ฅผ ์ ์šฉํ•ด ๋ณด๊ณ , Custom Hook๊ณผ
React.lazy()์™€ Suspense๋ฅผ ์ด์šฉํ•˜์—ฌ React ์•ฑ์„ ์ง์ ‘ ๋ฆฌํŒฉํ† ๋ง์„ ํ•ด๋ด…๋‹ˆ๋‹ค.

json-server ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ด๋ฒˆ ๊ณผ์ œ์—์„œ๋Š” ์กฐ๊ธˆ ํŠน๋ณ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

json-server๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์—ฌ๋Ÿฌ๋ถ„์ด ์ง์ ‘ DB๋ฅผ ๋งŒ๋“ค๊ณ  ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ• 
ํ•„์š” ์—†์ด json ํŒŒ์ผ์„ ์ด์šฉํ•˜์—ฌ REST API ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•ด ์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

// ์„ค์น˜
npm i -g json-server

// ์„œ๋ฒ„ ์—ด๊ธฐ
cd data
json-server --watch data.json --port 3001

๐Ÿ”ฅ Bare Minimum Requirements


  • App ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ(App.js)
    • react.lazy()์™€ suspense๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•ฉ๋‹ˆ๋‹ค.
  • BlogDetail ์ปดํฌ๋„ŒํŠธ(BlogDetail.js)
    • ํ˜„์žฌ๋Š” ๊ฐœ๋ณ„ ๋ธ”๋กœ๊ทธ ๋‚ด์šฉ์œผ๋กœ ์ง„์ž…ํ•ด๋„ ๋‚ด์šฉ์ด ๋ณด์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
      • useParams()์„ ์ด์šฉํ•˜์—ฌ ๊ฐœ๋ณ„ id๋ฅผ ๋ฐ›์•„์™€ ๊ฐœ๋ณ„ ๋ธ”๋กœ๊ทธ์˜ ๋‚ด์šฉ์ด ๋ณด์ผ ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ด…๋‹ˆ๋‹ค.
    • delete ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋‹ค์‹œ home์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      • useNavigate()๋ฅผ ์ด์šฉํ•˜์—ฌ handleDeleteClick ํ•จ์ˆ˜์˜ ๋กœ์ง์„ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.
    • ํ•˜ํŠธ๋ฅผ ๋ˆ„๋ฅด๋ฉด home์—์„œ ์ƒˆ๋กœ๊ณ ์นจ์„ ํ–ˆ์„ ๋•Œ ์ˆซ์ž๊ฐ€ ์˜ฌ๋ผ๊ฐ€์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      • isLike์™€ blog.likes๋ฅผ ์ด์šฉํ•˜์—ฌ handleLikeClickํ•จ์ˆ˜์˜ ๋กœ์ง์„ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.
    • isLike์— ์˜ํ•ด ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์œผ๋กœ ๋นจ๊ฐ„ ํ•˜ํŠธ(โค๏ธ)์™€ ํ•˜์–€ ํ•˜ํŠธ(๐Ÿค)๊ฐ€ ๋ฒˆ๊ฐˆ์•„ ๋ณด์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • CreateBlog ์ปดํฌ๋„ŒํŠธ(CreateBlog.js)
    • ๋“ฑ๋ก ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๊ฒŒ์‹œ๋ฌผ์ด ๋“ฑ๋ก์ด ๋˜๋ฉฐ home์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    • fetch์™€ useNavigate๋ฅผ ์ด์šฉํ•˜์—ฌ handleSubmit ์ด๋ฒคํŠธ๋ฅผ ์™„์„ฑํ•ด ๋ด…๋‹ˆ๋‹ค.
  • UseFetch ์ปดํฌ๋„ŒํŠธ(UseFetch.js)
    • GET ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๋Š” useEffect hook์€ ์ปดํฌ๋„ŒํŠธ ๋‚ด ์—ฌ๊ธฐ์ €๊ธฐ ์กด์žฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • ํ•ด๋‹น hook์€ ๋ฐ˜๋ณต์ด ๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ์œผ๋ฏ€๋กœ ์–ด๋–ป๊ฒŒ custom hook์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•ด ๋ด…์‹œ๋‹ค.
    • util ํด๋” ๋‚ด์— ์กด์žฌํ•˜๋Š” useFetch์— custom hook์„ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.
      • useState๋ฅผ ์ด์šฉํ•˜์—ฌ data, isPending, error๋ฅผ ์ •์˜ํ•˜์„ธ์š”.
      • useFetch ์•ˆ์˜ ์ค‘์‹ฌ ๋กœ์ง์„ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”.


๐Ÿ’ฌ Review


Home ํ™”๋ฉด


Detail ํ™”๋ฉด (PATCH)


๊ธ€ ์ƒ์„ฑ (POST)


โš™๏ธ Code

profile
์•„์ด๋””์–ด๊ฐ€ ๋„˜์น˜๋Š” ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ ๊ฟˆ๊ฟ‰๋‹ˆ๋‹ค ๐Ÿ”ฅ

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

comment-user-thumbnail
2023๋…„ 7์›” 20์ผ

๋„ˆ๋ฌด ์ข‹์€ ๊ธ€์ด๋„ค์š”. ๊ณต์œ ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ