ํ™ˆ Modularizing React Applications with Established UI Patterns ์ •๋ฆฌ
ํฌ์ŠคํŠธ
์ทจ์†Œ

Modularizing React Applications with Established UI Patterns ์ •๋ฆฌ

๐Ÿ’ป ๋ฌธ์ œ

React ์™€ ๊ฐ™์€ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ๋„๊ตฌ๋Š” ๋ทฐ(view) ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋„๊ตฌ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์›์น™์ƒ view ์™€ ์—ฐ๊ด€๋˜์–ด ์žˆ๋Š” ์ฝ”๋“œ(view code) ๋งŒ ์กด์žฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, view ์™€ ์—ฐ๊ด€๋˜์–ด ์žˆ์ง€ ์•Š๋Š” ์ฝ”๋“œ(non-view code) ๊ฐ€ ์กด์žฌํ•˜๊ฒŒ ๋˜๋ฉด ์„œ๋น„์Šค์˜ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง์—๋”ฐ๋ผ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง€๊ฒŒ ๋˜๊ณ , ์œ ์ง€๋ณด์ˆ˜๋„ ์–ด๋ ค์›Œ ์ง€๊ฒŒ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, ์ฝ”๋“œ์˜ ๊ฐ ๋ถ€๋ถ„์ด ์–ด๋–ค ์—ญํ• ์„ ํ•˜๋Š”์ง€ ๋ถ„์„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, view code ์™€ non-view code ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ , non-view code ๋ฅผ ์ฑ…์ž„์— ๋”ฐ๋ผ ๋”์šฑ ์„ธ๋ถ„ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
ํ™•์žฅ๊ฐ€๋Šฅํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์šฉ์ดํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์›๋ฌธ์—์„œ ์ œ์‹œํ•œ ๋‹จ๊ณ„์™€, ํ•ด๋‹น ๋‹จ๊ณ„๋“ค์„ ์ ์šฉํ•ด ๋ฆฌํŽ™ํ† ๋งํ•œ ์˜ˆ์‹œ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ป ํ™•์žฅ์„ฑ์žˆ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ๊ณ„

๐Ÿ‘จโ€๐Ÿ’ป ๋‹จ์ผ ์ปดํฌ๋„ŒํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(Single Component Application)

ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

single-component-application.png

์œ„ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์— ๋„คํŠธ์›Œํฌ ์š”์ฒญ, ์ƒํƒœ ๊ด€๋ฆฌ, ๋„๋ฉ”์ธ ๋กœ์ง์ด ๋ชจ๋‘ ์กด์žฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ํŒŒ์•…ํ•˜๋Š”๊ฒƒ์ด ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป ๋‹ค์ค‘ ์ปดํฌ๋„ŒํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(Multiple Component Application)

๋‹จ์ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์•„๋ž˜์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„ํ• ํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. multiple-component-application.png

ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ฒŒ๋˜๋ฉด ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป Hooks ์„ ์ด์šฉํ•œ ์ƒํƒœ ๊ด€๋ฆฌ(State management with hooks)

๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, view ์—์„œ ์‚ฌ์šฉํ•  ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•˜๋Š” ๋“ฑ์˜ ๋กœ์ง์€ non-view code ๋กœ ๋ถ„๋ฅ˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์ปดํฌ๋„ŒํŠธ์™€ ๊ฐ™์ด ์œ„์น˜ํ•˜๋Š”๊ฒƒ์ด ์ ์ ˆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React ์˜ ๊ฒฝ์šฐ ์ด๋Ÿฐ ๋กœ์ง๋“ค์„ hook ์„ ์‚ฌ์šฉํ•ด UI ์™€ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

state-management-with-hooks

์ถ”๊ฐ€๋กœ, ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์— ์ƒํƒœ๋“ค์ด ๋งŽ์€ ๊ฒฝ์šฐ๋„ hook ์„ ์ด์šฉํ•ด ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ€ํ„ฐ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป ๋น„์ฆˆ๋‹ˆ์Šค ๋ชจ๋ธ์˜ ๋“ฑ์žฅ(Business models emerged)

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

business-models-emerged

๋ถ„๋ฆฌํ•œ ๋„๋ฉ”์ธ ๋กœ์ง๋“ค์€ non-view code ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ƒ์† ๋˜๋Š” ๋‹คํ˜•์„ฑ๋“ฑ๊ณผ ๊ฐ™์€ OOP ๋ฅผ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ป ์›์น™ ์ ์šฉํ•ด ๋ฆฌํŽ™ํ† ๋ง ํ•ด๋ณด๊ธฐ

์œ„์—์„œ ์‚ดํŽด๋ณธ ์›์น™์„ ๋ฐ”ํƒ•์œผ๋กœ ์‡ผํ•‘๋ชฐ ์„œ๋น„์Šค์—์„œ ๊ฒฐ์ œ ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์™€ ๋กœ์ง์„ ๋ฆฌํŽ™ํ† ๋ง ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

original-payment-code

์œ„์˜ Payment ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฒฐ์ œ ๋ฐฉ๋ฒ•๋“ค์„ ์„œ๋ฒ„์—์„œ ๋ถˆ๋Ÿฌ์˜จ ํ›„, ๋ฐ์ดํ„ฐ ๊ฐ€๊ณต ํ›„ view ์— ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป ๋ฌธ์ œ์ 

Payment ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๋กœ์ง, ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ ๋งตํ•‘ ๋กœ์ง, ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ๋ฐ›์•„์˜จ ๊ฒฐ์ œ ๋ฐฉ๋ฒ•์„ ๋ Œ๋”๋ง ํ•˜๋Š” ๋กœ์ง, Payment ์ปดํฌ๋„ŒํŠธ ์ž์ฒด์˜ ๋ Œ๋”๋ง ๋กœ์ง ์„ ๋ชจ๋‘ ์ดํ•ดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

original-payment-code-separate

๐Ÿ‘จโ€๐Ÿ’ป ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ์ถ”์ถœ์„ ํ†ตํ•œ view ๋ถ„ํ•  (= ๋‹ค์ค‘ ์ปดํฌ๋„ŒํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)

๊ฒฐ์ œ ๋ฐฉ๋ฒ• ๋ Œ๋”๋ง ๋กœ์ง์„ Payment ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

original-payment-code-payment-method

PaymentMethod ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด Payment ์ปดํฌ๋„ŒํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹จ์ˆœํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. original-payment-code-apply-payment-methods

๐Ÿ‘จโ€๐Ÿ’ป View code ์™€ non-view code ์ฝ”๋“œ ๋ถ„๋ฆฌ (= Hooks ์„ ์ด์šฉํ•œ ์ƒํƒœ๊ด€๋ฆฌ)

non-view code ์™€ ๊ทธ์™€ ๊ด€๋ จ๋œ ์ƒํƒœ๋ฅผ hook ์œผ๋กœ ๋ถ„๋ฆฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

original-payment-code-hook

๐Ÿ‘จโ€๐Ÿ’ป ๋กœ์ง์„ ์บก์Šํ™”ํ•˜๋Š” ๋ฐ์ดํ„ฐ ๋ชจ๋ธ๋ง (= ๋น„์ฆˆ๋‹ˆ์Šค ๋ชจ๋ธ์˜ ๋“ฑ์žฅ)

์œ„ ๋‹จ๊ณ„๋ฅผ ํ†ตํ•ด Payment ์ปดํฌ๋„ŒํŠธ์˜ view-code ๋Š” ์ž‘์€ ๋‹จ์œ„๋กœ ๋‚˜๋ˆ  ์žฌ์‚ฌ์šฉ์„ฑ์ด ๋†’์•„์กŒ๊ณ , non-view code ๋Š” view code ๋กœ ๋ถ€ํ„ฐ ๋ถ„๋ฆฌ๋˜์–ด ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ๋†’์•„์กŒ์Šต๋‹ˆ๋‹ค.
์ด์ œ ๋ถ„๋ฆฌ๋œ non-view code ๋ฅผ ์ฑ…์ž„์— ๋”ฐ๋ผ ์„ธ๋ถ„ํ™” ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„  PaymentMethod ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ธฐ๋ณธ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง (method.provider === 'cash') ์„ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด ๋กœ์ง์€ ๋ฐ์ดํ„ฐ์˜ ํ˜•ํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ ์ˆ˜์ •์ด ํ•„์š”ํ•˜๋ฉฐ, ๋งŒ์•ฝ ํฉ์–ด์ ธ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ๋” ํฐ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ๋Š” usePaymentMethods hook ์—์„œ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋กœ์ง์„ ํด๋ž˜์Šค๋กœ ๋ถ„๋ฆฌํ•œ ํ›„, ํ•ด๋‹น ํด๋ž˜์Šค์— ๊ฒ€์ฆ๋กœ์ง์„ ํฌํ•จํ•˜๋ฉด ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

original-payment-code-business-logic

๐Ÿ“” ์ฐธ๊ณ ์ž๋ฃŒ

[๋ฒˆ์—ญ] ์ž˜ ์•Œ๋ ค์ง„ UI ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์•กํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ชจ๋“ˆํ™”ํ•˜๊ธฐ
Modularizing React Applications with Established UI Patterns

์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

React Query - ๊ธฐ๋ณธ์„ค์ • ์‚ดํŽด๋ณด๊ธฐ

React re-rendering ์‚ดํŽด๋ณด๊ธฐ