Unit3 - [React] ์‹ฌํ™”

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

โœ… TIL


์ด๋ฒˆ ์œ ๋‹›์—์„œ๋Š” ๋ฆฌ์•กํŠธ์˜ ๋™์ž‘ ๋ฐฉ์‹๊ณผ, ๋ฆฌ์•กํŠธ Hooks์— ๋Œ€ํ•ด ๋ฐฐ์šฐ๋ฉฐ ๋ฆฌ์•กํŠธ๋ฅผ ์ข€ ๋” ์‹ฌ๋„ ์žˆ๊ฒŒ ํ•™์Šตํ•œ๋‹ค.
๋ฆฌ์•กํŠธ์˜ ๋™์ž‘ ๋ฐฉ์‹๊ณผ, ๋ฆฌ์•กํŠธ Hooks์— ๋Œ€ํ•ด ํ•™์Šตํ•˜์‹ ๋‹ค๋ฉด ๋”์šฑ ๋ฉ‹์ง„ ์•ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.



Virtual DOM


React๋Š” UI์˜ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๊ณ  ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚œ ์š”์†Œ๋“ค์„
๋น ๋ฅด๊ฒŒ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋„๋ก Virtual DOM์ด๋ผ๋Š” ๊ฐ€์ƒ์˜ DOM ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

์ด ๊ฐ€์ƒ์˜ DOM ๊ฐ์ฒด๋Š” ์‹ค์ œ DOM์˜ ์‚ฌ๋ณธ ๊ฐ™์€ ๊ฐœ๋…์œผ๋กœ, React๋Š” ์‹ค์ œ DOM ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜์—ฌ ์กฐ์ž‘ํ•˜๋Š” ๋Œ€์‹  ์ด ๊ฐ€์ƒ์˜ DOM ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜์—ฌ ๋ณ€ํ™” ์ „๊ณผ ๋ณ€ํ™” ํ›„๋ฅผ ๋น„๊ตํ•˜๊ณ  ๋ฐ”๋€ ๋ถ€๋ถ„๋งŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.


Real DOM (DOM)

DOM์€ Document Object Model์˜ ์•ฝ์ž๋กœ, ๋œป์„ ๊ทธ๋Œ€๋กœ ํ’€์ž๋ฉด ๋ฌธ์„œ ๊ฐ์ฒด ๋ชจ๋ธ์„ ์˜๋ฏธํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ฌธ์„œ ๊ฐ์ฒด๋ž€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ JavaScript์™€ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŒ… ์–ธ์–ด๊ฐ€ <html>, <head>, <body>์™€ ๊ฐ™์€ ํƒœ๊ทธ๋“ค์— ์ ‘๊ทผํ•˜๊ณ  ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฌธ์„œ๋ฅผ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ฐ์ฒดํ™”ํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ž๋ฉด DOM์€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ HTML ๋ฌธ์„œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํŠธ๋ฆฌ ๊ตฌ์กฐํ™”ํ•œ ๊ฐ์ฒด ๋ชจ๋ธ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์ด๋ฏธ์ง€์˜ ์™ผ์ชฝ๊ณผ ๊ฐ™์€ HTML ๋ฌธ์„œ๊ฐ€ ์žˆ์„ ๋•Œ ์ด๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฝ๋Š”๋‹ค๋ฉด ์ด๋ฏธ์ง€์˜ ์˜ค๋ฅธ์ชฝ๊ณผ ๊ฐ™์€ DOM์ด ์ƒ์„ฑ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  querySelector, addEventListener์™€ ๊ฐ™์€ DOM API๋ฅผ ํ†ตํ•ด ๋ฌธ์„œ์˜ ์š”์†Œ๋“ค์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.


DOM์˜ ์กฐ์ž‘ ์†๋„๊ฐ€ ๋Š๋ ค์ง€๋Š” ์ด์œ 

์•ž์„œ ์„ค๋ช…ํ–ˆ๋“ฏ์ด DOM์€ ๊ณ„์ธต์  ํ˜•ํƒœ์˜ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.

์ž๋ฃŒ๊ตฌ์กฐ ์ค‘์—์„œ๋„ ํŠนํžˆ ํŠธ๋ฆฌ๋Š” โ€œ๋ฐ์ดํ„ฐ ์ €์žฅ"์˜ ์˜๋ฏธ๋ณด๋‹ค๋Š” โ€œ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ํšจ๊ณผ์ ์œผ๋กœ ํƒ์ƒ‰โ€ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋ฏ€๋กœ, ๋น ๋ฅธ ์ž๋ฃŒ ํƒ์ƒ‰ ์„ฑ๋Šฅ์ด ์žฅ์ ์ธ ์ž๋ฃŒ๊ตฌ์กฐ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋Ÿฐ ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ๋œ DOM์€ JavaScript์™€ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŒ… ์–ธ์–ด๊ฐ€
์ ‘๊ทผํ•˜๊ณ  ํƒ์ƒ‰ํ•˜๋Š” ์†๋„๊ฐ€ ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ ๋ฐ ์—…๋ฐ์ดํŠธ ์†๋„ ๋˜ํ•œ ๋น ๋ฅด๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ DOM์ด ๋ณ€๊ฒฝ๋˜๊ณ  ์—…๋ฐ์ดํŠธ๊ฐ€ ๋œ๋‹ค๋Š” ๊ฒƒ์€ ๊ฒฐ๊ตญ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ Œ๋”๋ง ์—”์ง„ ๋˜ํ•œ ๋ฆฌํ”Œ๋กœ์šฐ(Reflow)ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋ธŒ๋ผ์šฐ์ €๋Š” ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ DOM ํŠธ๋ฆฌ์™€ CSSOM ํŠธ๋ฆฌ๋ฅผ ํ† ๋Œ€๋กœ Render ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ ์š”์†Œ๊ฐ€ ๋ฐฐ์น˜๋  ๊ณต๊ฐ„์„ ๊ณ„์‚ฐ(Layout)ํ•œ ๋’ค ์ด๋ฅผ ํ™”๋ฉด์— ๊ทธ๋ ค๋‚ธ๋‹ค.(Paint)

๋งŒ์•ฝ DOM์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ์—…๋ฐ์ดํŠธ๋œ ์š”์†Œ์™€ ๊ทธ์— ํ•ด๋‹นํ•˜๋Š” ์ž์‹ ์š”์†Œ๋“ค์— ์˜ํ•ด DOM ํŠธ๋ฆฌ๋ฅผ ์žฌ๊ตฌ์ถ•ํ•˜๊ฒŒ ๋œ๋‹ค.

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

๋”ฐ๋ผ์„œ JavaScript๋ฅผ ํ†ตํ•œ DOM ์กฐ์ž‘์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ์ด์— ๋Œ€ํ•œ ๋ฆฌํ”Œ๋กœ์šฐ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ DOM ์—…๋ฐ์ดํŠธ ๋น„์šฉ์ด ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด๊ฒ ๋‹ค.

์œ„ ์ด๋ฏธ์ง€์™€ ๊ฐ™์ด 6๊ฐœ์˜ ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ๋Š” ํ™”๋ฉด์—์„œ ๋‹จ 1๊ฐœ์˜ ์ฝ˜ํ…์ธ ๋งŒ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ๋‹ค.

๋‚˜๋จธ์ง€ 5๊ฐœ์˜ ์ฝ˜ํ…์ธ ๋Š” ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ  ํ•ด๋‹น ์ฝ˜ํ…์ธ ๋งŒ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•˜์ง€๋งŒ,
์‹ค์ œ DOM์„ ์กฐ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ์ฝ˜ํ…์ธ ๋งŒ ๋ณ€๊ฒฝ๋  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‚˜๋จธ์ง€ ์ฝ˜ํ…์ธ ๋„ ๋‹ค์‹œ ๊ทธ๋ฆฌ๊ฒŒ ๋  ์ˆ˜ ์žˆ๋‹ค.

์ด ์˜ˆ์‹œ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ์„ฑ๋Šฅ์— ํฌ๊ฒŒ ๋ฌธ์ œ๋ฅผ ๋ผ์น˜์ง€ ์•Š๊ฒ ์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ๋ชจ๋˜ ์›น์—์„œ๋Š” ๋งŽ์€ ์–‘์˜ DOM ์กฐ์ž‘์ด ์ด๋ฃจ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋ฆฌํ”Œ๋กœ์šฐ๋กœ ์ธํ•œ ๋น„ํšจ์œจ์ ์ธ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ๊ทน๋‹จ์ ์ธ ์˜ˆ๋กœ ํ”„๋ ˆ์ž„ ๋“œ๋กญ(Frame Drop)๊ณผ ๊ฐ™์€ ์น˜๋ช…์ ์ธ UX ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฒฐ๊ตญ โ€œ๋ฐ”๋€ ๋ถ€๋ถ„๋งŒ ๋น„๊ตํ•ด์„œ ๊ทธ ๋ถ€๋ถ„๋งŒ ๋ Œ๋”๋งํ•  ์ˆ˜๋Š” ์—†์„๊นŒ?โ€œ๋ผ๋Š”
์•„์ด๋””์–ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ React์˜ Virtual DOM์ด ๋“ฑ์žฅํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.


Virtual DOM์ด๋ž€?

๊ฐ€์ƒ DOM์€ ์‹ค์ œ DOM๊ณผ ๋™๊ธฐํ™”๋˜์–ด, ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๊ฐ€์ƒ DOM์„ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์—ฌ ์ด์ „ ์ƒํƒœ์™€ ๋น„๊ตํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์‹ค์ œ DOM์— ๋ฐ˜์˜ํ•˜์—ฌ ์—…๋ฐ์ดํŠธํ•˜๋ฏ€๋กœ, ์ „์ฒด UI๋ฅผ ๋‹ค์‹œ ๊ทธ๋ฆฌ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

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

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


Virtual DOM์˜ ํ˜•ํƒœ

๊ฐ€์ƒ DOM์€ ์ถ”์ƒํ™”๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. DOM ํŠธ๋ฆฌ ํ•˜๋‚˜๋ฅผ ์˜ˆ์‹œ๋กœ ์‚ดํŽด๋ณด๊ฒ ๋‹ค.

์ด DOM ํŠธ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด JavaScript ๊ฐ์ฒด๋กœ๋„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

const vDom = {
	tagName: "html",
	children: [
		{ tagName: "head" },
		{ tagName: "body",
			children: [
				tagName: "ul",
				attributes: { "class": "list"},
				children: [
					{
						tagName: "li",
						attributes: { "class": "list_item" },
						textContent: "List item"
					}
				]
			]
		}
	]
}


์ด๊ฒƒ์„ ๊ฐ€์ƒ DOM์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด ๋ณด๊ฒ ๋‹ค.

์‹ค์ œ DOM๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐ€์ƒ DOM ๋˜ํ•œ HTML ๋ฌธ์„œ ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค. ๋˜ํ•œ ์ถ”์ƒํ™”๋งŒ ๋˜์—ˆ์„ ๋ฟ ํ‰๋ฒ”ํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์ด๋ฏ€๋กœ ์‹ค์ œ DOM์„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ ๋„ ํ•„์š”ํ•œ ๋งŒํผ ์ž์œ ๋กญ๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ฐ€์ƒ DOM์€ ๋ฆฌ์•กํŠธ์—์„œ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ๋‚˜ ์†์„ฑ์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋ฉฐ,
๋ฆฌ์•กํŠธ๋Š” ์ด์ „ ๊ฐ€์ƒ DOM๊ณผ ์ƒˆ๋กœ์šด ๊ฐ€์ƒ DOM์„ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ์‹ค์ œ DOM์— ๋ฐ˜์˜ํ•œ๋‹ค.


Virtual DOM์˜ ๋™์ž‘ ๊ณผ์ •

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋™์˜์ƒ ์‚ฌ์ดํŠธ์—์„œ ํŠน์ • ์ธ๋„ค์ผ ํด๋ฆญ ์‹œ, ๋ชจ๋‹ฌ ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ์ƒํ•ด ๋ณด์ž.
๋ฆฌ์•กํŠธ์—์„  ์ด์™€ ๊ฐ™์€ ์ƒํƒœ ๋ณ€ํ™”์— ์–ด๋–ป๊ฒŒ ๋Œ€์‘ํ• ๊นŒ?

๋ฆฌ์•กํŠธ๋Š” ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…(e.g. ์ด๋ฒคํŠธ)์ด ์ผ์–ด๋‚ฌ์„ ๋•Œ,
๊ฐ€์ƒ DOM์— ์ €์žฅ๋œ ์ด์ „ ์ƒํƒœ์™€ ๋ณ€๊ฒฝ๋œ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋น„๊ตํ•œ๋‹ค.

์ด ๋น„๊ต ๊ณผ์ •์—์„œ React๋Š” Diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„์„ ๊ฐ์ง€ํ•œ๋‹ค.

๋”ฐ๋ผ์„œ React์—์„œ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” Diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์ด๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋„๋ก
์ง์ ‘ ํ• ๋‹น์ด ์•„๋‹Œ setState์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•ด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฐ€์ƒ DOM๊ณผ ๋ณ€๊ฒฝ๋œ ์ƒˆ๋กœ์šด ๊ฐ€์ƒ DOM์„ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์‹ค์ œ DOM์— ๋ฐ˜์˜ํ•˜์—ฌ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ์ด๊ฒƒ์„ Reconciliation, ์ฆ‰ ์žฌ์กฐ์ •์ด๋ผ๊ณ  ํ•œ๋‹ค.

์ด ๊ณผ์ •์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์ด๋ฅผ ์ผ์ผ์ด ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ผ๊ด„์ ์œผ๋กœ ํ•œ ๋ฒˆ์— ์—…๋ฐ์ดํŠธ(Batch Update)ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๊ณ  ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.


Virtual DOM์€ ๋น ๋ฅด๋‹ค?

๊ฐ€์ƒ DOM์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‹ค์ œ DOM์„ ์ง์ ‘ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋น ๋ฅด๋‹ค๋Š” ๊ฒƒ์ด ๋งž์ง€๋งŒ,
๋ชจ๋“  ๊ฒฝ์šฐ์— ๊ทธ๋ ‡์ง€๋Š” ์•Š๋‹ค. ๋•Œ๋กœ๋Š” ์ง์ ‘ DOM์„ ์กฐ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋น ๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

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



Diffing Algorithm


React๊ฐ€ ๊ธฐ์กด ๊ฐ€์ƒ DOM๊ณผ ๋ณ€๊ฒฝ๋œ ์ƒˆ๋กœ์šด ๊ฐ€์ƒ DOM์„ ๋น„๊ตํ•  ๋•Œ, React ์ž…์žฅ์—์„œ๋Š” ๋ณ€๊ฒฝ๋œ ์ƒˆ๋กœ์šด ๊ฐ€์ƒ DOM ํŠธ๋ฆฌ์— ๋ถ€ํ•ฉํ•˜๋„๋ก ๊ธฐ์กด์˜ UI๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ผ ํ•„์š”๊ฐ€ ์žˆ์—ˆ๋‹ค.

์ฆ‰ ํ•˜๋‚˜์˜ ํŠธ๋ฆฌ๋ฅผ ๋‹ค๋ฅธ ํŠธ๋ฆฌ๋กœ ๋ณ€ํ˜•์„ ์‹œํ‚ค๋Š” ๊ฐ€์žฅ ์ž‘์€ ์กฐ์ž‘ ๋ฐฉ์‹์„ ์•Œ์•„๋‚ด์•ผ๋งŒ ํ–ˆ๋Š”๋ฐ,
์•Œ์•„๋‚ธ ์กฐ์ž‘ ๋ฐฉ์‹ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ O(n^3)์˜ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค.

๋งŒ์•ฝ ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ทธ๋Œ€๋กœ React์— ์ ์šฉํ•œ๋‹ค๋ฉด 1000๊ฐœ์˜ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์‹ค์ œ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด 10์–ต(1000^3)๋ฒˆ์˜ ๋น„๊ต ์—ฐ์‚ฐ์„ ํ•ด์•ผ๋งŒ ํ•œ๋‹ค. ์‚ฌ์‹ค ์ด๊ฒƒ์€ ๋„ˆ๋ฌด ๋น„์‹ผ ์—ฐ์‚ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ๋‘ ๊ฐ€์ง€์˜ ๊ฐ€์ •์„ ๊ฐ€์ง€๊ณ  ์‹œ๊ฐ„ ๋ณต์žก๋„ O(n)์˜ ์ƒˆ๋กœ์šด ํœด๋ฆฌ์Šคํ‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜(Heuristic Algorithm)์„ ๊ตฌํ˜„ํ•ด ๋‚ธ๋‹ค.

๋‘ ๊ฐ€์ง€ ๊ฐ€์ •์€ ์ด๊ฒƒ์ด๋‹ค.

  1. ๊ฐ๊ธฐ ์„œ๋กœ ๋‹ค๋ฅธ ๋‘ ์š”์†Œ๋Š” ๋‹ค๋ฅธ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•  ๊ฒƒ์ด๋‹ค.
  2. ๊ฐœ๋ฐœ์ž๊ฐ€ ์ œ๊ณตํ•˜๋Š” key ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ , ์—ฌ๋Ÿฌ ๋ฒˆ ๋ Œ๋”๋ง์„ ๊ฑฐ์ณ๋„ ๋ณ€๊ฒฝ๋˜์ง€ ๋ง์•„์•ผ ํ•˜๋Š” ์ž์‹ ์š”์†Œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์‹ค์ œ ์ด ๋‘ ๊ฐ€์ •์€ ๊ฑฐ์˜ ๋ชจ๋“  ์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋“ค์–ด๋งž๊ฒŒ ๋œ๋‹ค.
์—ฌ๊ธฐ์„œ React๋Š” ๋น„๊ต ์•Œ๊ณ ๋ฆฌ์ฆ˜(Diffing Algorithm)์„ ์‚ฌ์šฉํ•œ๋‹ค.


React๊ฐ€ DOM ํŠธ๋ฆฌ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๋ฐฉ๋ฒ•

React๋Š” ๊ธฐ์กด์˜ ๊ฐ€์ƒ DOM ํŠธ๋ฆฌ์™€ ์ƒˆ๋กญ๊ฒŒ ๋ณ€๊ฒฝ๋œ ๊ฐ€์ƒ DOM ํŠธ๋ฆฌ๋ฅผ ๋น„๊ตํ•  ๋•Œ, ํŠธ๋ฆฌ์˜ ๋ ˆ๋ฒจ ์ˆœ์„œ๋Œ€๋กœ ์ˆœํšŒํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํƒ์ƒ‰ํ•œ๋‹ค. ์ฆ‰ ๊ฐ™์€ ๋ ˆ๋ฒจ(์œ„์น˜)๋ผ๋ฆฌ ๋น„๊ตํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.

์ด๋Š” ๋„ˆ๋น„ ์šฐ์„  ํƒ์ƒ‰(BFS)์˜ ์ผ์ข…์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

React๋Š” ์ด๋Ÿฐ ์‹์œผ๋กœ ๋™์ผ ์„ ์ƒ์— ์žˆ๋Š” ๋…ธ๋“œ๋ฅผ ํŒŒ์•…ํ•œ ๋’ค, ๋‹ค์Œ ์ž์‹ ์„ธ๋Œ€์˜ ๋…ธ๋“œ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ํŒŒ์•…ํ•ด ๋‚˜๊ฐ„๋‹ค.


๋‹ค๋ฅธ ํƒ€์ž…์˜ DOM ์—˜๋ฆฌ๋จผํŠธ์ธ ๊ฒฝ์šฐ

๊ทธ๋Ÿฐ๋ฐ DOM ํŠธ๋ฆฌ๋Š” ๊ฐ HTML ํƒœ๊ทธ๋งˆ๋‹ค ๊ฐ๊ฐ์˜ ๊ทœ์น™์ด ์žˆ์–ด ๊ทธ ์•„๋ž˜ ๋“ค์–ด๊ฐ€๋Š” ์ž์‹ ํƒœ๊ทธ๊ฐ€ ํ•œ์ •์ ์ด๋ผ๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. (์˜ˆ๋ฅผ ๋“ค์–ด <ul> ํƒœ๊ทธ ๋ฐ‘์—๋Š” <li> ํƒœ๊ทธ๋งŒ ์™€์•ผ ํ•œ๋‹ค๋˜๊ฐ€, <p> ํƒœ๊ทธ ์•ˆ์— <p> ํƒœ๊ทธ๋ฅผ ๋˜ ์“ฐ์ง€ ๋ชปํ•˜๋Š” ๊ฒƒ์ด๋‹ค.) ์ž์‹ ํƒœ๊ทธ์˜ ๋ถ€๋ชจ ํƒœ๊ทธ ๋˜ํ•œ ์ •ํ•ด์ ธ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ€๋ชจ ํƒœ๊ทธ๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค๋ฉด React๋Š” ์ด์ „ ํŠธ๋ฆฌ๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•ด ๋ฒ„๋ฆฐ๋‹ค.

<div>
	<Counter />
</div>

// ๋ถ€๋ชจ ํƒœ๊ทธ๊ฐ€ div์—์„œ span์œผ๋กœ ๋ฐ”๋€๋‹ค.
<span>
	<Counter />
</span>


์ด๋ ‡๊ฒŒ ๋ถ€๋ชจ ํƒœ๊ทธ๊ฐ€ ๋ฐ”๋€Œ์–ด๋ฒ„๋ฆฌ๋ฉด, React๋Š” ๊ธฐ์กด์˜ ํŠธ๋ฆฌ๋ฅผ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด์ „์˜ DOM ๋…ธ๋“œ๋“ค์€ ์ „๋ถ€ ํŒŒ๊ดด๋œ๋‹ค. ๋ถ€๋ชจ ๋…ธ๋“œ์˜€๋˜ <div>๊ฐ€ <span>์œผ๋กœ ๋ฐ”๋€Œ์–ด๋ฒ„๋ฆฌ๋ฉด ์ž์‹ ๋…ธ๋“œ์ธ <Counter />๋Š” ์™„์ „ํžˆ ํ•ด์ œ๋œ๋‹ค. ์ฆ‰ ์ด์ „ <div> ํƒœ๊ทธ ์† <Counter />๋Š” ํŒŒ๊ดด๋˜๊ณ  <span> ํƒœ๊ทธ ์† ์ƒˆ๋กœ์šด <Counter />๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋œ๋‹ค. ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹คํ–‰๋˜๋ฉด์„œ ๊ธฐ์กด์˜ ์ปดํฌ๋„ŒํŠธ๋Š” ์™„์ „ํžˆ ํ•ด์ œ(Unmount)๋˜์–ด๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— <Counter />๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋˜ ๊ธฐ์กด์˜ state ๋˜ํ•œ ํŒŒ๊ดด๋œ๋‹ค.


๊ฐ™์€ ํƒ€์ž…์˜ DOM ์—˜๋ฆฌ๋จผํŠธ์ธ ๊ฒฝ์šฐ

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

<div className="before" title="stuff" />

// ๊ธฐ์กด์˜ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ํƒœ๊ทธ๋Š” ๋ฐ”๋€Œ์ง€ ์•Š์€ ์ฑ„ className๋งŒ ๋ฐ”๋€Œ์—ˆ๋‹ค.
<div className="after" title="stuff" />


React๋Š” ๋‘ ์š”์†Œ๋ฅผ ๋น„๊ตํ–ˆ์„ ๋•Œ className๋งŒ ์ˆ˜์ •๋˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋œ๋‹ค.
className before์™€ after๋Š” ๊ฐ์ž ์ด๋Ÿฐ ์Šคํƒ€์ผ์„ ๊ฐ–๊ณ  ์žˆ๋‹ค๊ณ  ํ•ด๋ณด๊ฒ ๋‹ค.

// className์ด before์ธ ์ปดํฌ๋„ŒํŠธ
<div style={{color: 'red', fontWeight: 'bold"}} title="stuff" />

// className์ด after์ธ ์ปดํฌ๋„ŒํŠธ
<div style={{color: 'green', fontWeight: 'bold"}} title="stuff" />


๋‘ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋น„๊ตํ–ˆ์„ ๋•Œ React๋Š” ์ •ํ™•ํžˆ color ์Šคํƒ€์ผ๋งŒ ๋ฐ”๋€Œ๊ณ  ์žˆ์Œ์„ ๋ˆˆ์น˜์ฑˆ๋‹ค. ๋”ฐ๋ผ์„œ React๋Š” color ์Šคํƒ€์ผ๋งŒ ์ˆ˜์ •ํ•˜๊ณ  fontWeight ๋ฐ ๋‹ค๋ฅธ ์š”์†Œ๋Š” ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋‚˜์˜ DOM ๋…ธ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•œ ๋’ค React๋Š” ๋’ค์ด์–ด์„œ ํ•ด๋‹น ๋…ธ๋“œ๋“ค ๋ฐ‘์˜ ์ž์‹๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋™์‹œ์— ์ˆœํšŒํ•˜๋ฉด์„œ ์ฐจ์ด๊ฐ€ ๋ฐœ๊ฒฌ๋  ๋•Œ๋งˆ๋‹ค ๋ณ€๊ฒฝํ•œ๋‹ค. ์ด๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.


์ž์‹ ์—˜๋ฆฌ๋จผํŠธ์˜ ์žฌ๊ท€์  ์ฒ˜๋ฆฌ

์˜ˆ๋ฅผ ๋“ค๋ฉด ์ด๋ ‡๊ฒŒ ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ๋ณ€๊ฒฝ์ด ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ๋‹ค.

<ul>
  <li>first</li>
  <li>second</li>
</ul>

// ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ์˜ ๋์— ์ƒˆ๋กœ์šด ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.
<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>


React๋Š” ๊ธฐ์กด <ul>๊ณผ ์ƒˆ๋กœ์šด <ul>์„ ๋น„๊ตํ•  ๋•Œ ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์œ„์—์„œ๋ถ€ํ„ฐ ์•„๋ž˜๋กœ ๋น„๊ตํ•˜๋ฉด์„œ ๋ฐ”๋€ ์ ์„ ์ฐพ๋Š”๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ์ƒ๋Œ€๋กœ React๋Š” ์ฒซ ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ๋“ค๊ณผ ๋‘ ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ๋“ค์ด ์ผ์น˜ํ•˜๋Š” ๊ฑธ ํ™•์ธํ•œ ๋’ค ์„ธ ๋ฒˆ์งธ ์ž์‹ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ React๋Š” ์œ„์—์„œ ์•„๋ž˜๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ๋น„๊ตํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•˜์ง€ ์•Š๊ณ  ๋ฆฌ์ŠคํŠธ์˜ ์ฒ˜์Œ์— ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์‚ฝ์ž…ํ•˜๊ฒŒ ๋˜๋ฉด ์ด์ „์˜ ์ฝ”๋“œ์— ๋น„ํ•ด ํ›จ์”ฌ ๋‚˜์œ ์„ฑ๋Šฅ์„ ๋‚ด๊ฒŒ ๋œ๋‹ค.

<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

// ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ฒ˜์Œ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>


์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฉด React๋Š” ์šฐ๋ฆฌ์˜ ๊ธฐ๋Œ€๋Œ€๋กœ ์ตœ์†Œํ•œ์œผ๋กœ ๋™์ž‘ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋œ๋‹ค.
React๋Š” ์›๋ž˜์˜ ๋™์ž‘ํ•˜๋˜ ๋ฐฉ์‹๋Œ€๋กœ ์ฒ˜์Œ์˜ ๋…ธ๋“œ๋“ค์„ ๋น„๊ตํ•˜๊ฒŒ ๋œ๋‹ค.

์ฒ˜์Œ์˜ ์ž์‹ ๋…ธ๋“œ๋ฅผ ๋น„๊ตํ•  ๋•Œ, <li>Duke</li>์™€ <li>Connecticut</li>์œผ๋กœ ์ž์‹ ๋…ธ๋“œ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅด๋‹ค๊ณ  ์ธ์ง€ํ•˜๊ฒŒ ๋œ React๋Š” ๋ฆฌ์ŠคํŠธ ์ „์ฒด๊ฐ€ ๋ฐ”๋€Œ์—ˆ๋‹ค๊ณ  ๋ฐ›์•„๋“ค์ธ๋‹ค.

์ฆ‰ <li>Duke</li>์™€ <li>Villanova</li>๋Š” ๊ทธ๋Œ€๋กœ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ์ž์‹ ๋…ธ๋“œ๋Š” ์œ ์ง€์‹œ์ผœ๋„ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ์ง€ ๋ชปํ•˜๊ณ  ์ „๋ถ€ ๋ฒ„๋ฆฌ๊ณ  ์ƒˆ๋กญ๊ฒŒ ๋ Œ๋”๋ง ํ•ด๋ฒ„๋ฆฐ๋‹ค. ์ด๋Š” ๊ต‰์žฅํžˆ ๋น„ํšจ์œจ์ ์ธ ๋™์ž‘ ๋ฐฉ์‹์ด๋‹ค.

๊ทธ๋ž˜์„œ React๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด key๋ผ๋Š” ์†์„ฑ์„ ์ง€์›ํ•ด์„œ, ๊ฐ€์ƒ DOM์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

๋งŒ์ผ ๊ฐœ๋ฐœํ•  ๋‹น์‹œ key๋ผ๋Š” ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด
React์—์„œ key๊ฐ’์„ ๋‹ฌ๋ผ๊ณ  ๊ฒฝ๊ณ ๋ฌธ์„ ๋„์šฐ๋Š” ๊ฒƒ๋„ ์ด ๋•Œ๋ฌธ์ธ ๊ฒƒ์ด๋‹ค.

key๊ฐ’์ด ์—†๋Š” ๋…ธ๋“œ๋Š” ๋น„ํšจ์œจ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


ํ‚ค(key)

๋งŒ์•ฝ ์ž์‹ ๋…ธ๋“œ๋“ค์ด ์ด key๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค๋ฉด, React๋Š” ๊ทธ key๋ฅผ ์ด์šฉํ•ด
๊ธฐ์กด ํŠธ๋ฆฌ์˜ ์ž์‹๊ณผ ์ƒˆ๋กœ์šด ํŠธ๋ฆฌ์˜ ์ž์‹์ด ์ผ์น˜ํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

// key๊ฐ€ 2014์ธ ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ฒ˜์Œ์— ์ถ”๊ฐ€ํ•œ๋‹ค.
<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>


React๋Š” key ์†์„ฑ์„ ํ†ตํ•ด โ€˜2014โ€™๋ผ๋Š” ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ƒ๊ฒผ๊ณ , โ€˜2015โ€™, โ€˜2016โ€™ ํ‚ค๋ฅผ ๊ฐ€์ง„ ์—˜๋ฆฌ๋จผํŠธ๋Š” ๊ทธ์ € ์œ„์น˜๋งŒ ์ด๋™ํ–ˆ๋‹ค๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ React๋Š” ๊ธฐ์กด์˜ ๋™์ž‘ ๋ฐฉ์‹๋Œ€๋กœ ๋‹ค๋ฅธ ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์ถ”๊ฐ€๋œ ์—˜๋ฆฌ๋จผํŠธ๋งŒ ๋ณ€๊ฒฝํ•œ๋‹ค. ์ด key ์†์„ฑ์—๋Š” ๋ณดํ†ต ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์ƒ์˜ ์œ ๋‹ˆํฌํ•œ ๊ฐ’(ex. Id)์„ ๋ถ€์—ฌํ•ด ์ฃผ๋ฉด ๋œ๋‹ค. ํ‚ค๋Š” ์ „์—ญ์ ์œผ๋กœ ์œ ์ผํ•  ํ•„์š”๋Š” ์—†๊ณ , ํ˜•์ œ ์—˜๋ฆฌ๋จผํŠธ ์‚ฌ์ด์—์„œ๋งŒ ์œ ์ผํ•˜๋ฉด ๋œ๋‹ค.

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



Component์™€ Hook


Function Component์™€ Class Component


Hook์€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ์ด์ „์—๋Š” ํด๋ž˜์Šค(class) ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์—ˆ๋‹ค.
๋งŽ์€ React ๊ฐœ๋ฐœ์ž๋“ค์ด ์ด ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ React ์•ฑ์„ ๊ฐœ๋ฐœํ•ด ์™”๋‹ค.

๊ทธ๋ž˜์„œ React์˜ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋Š” ์กฐ๊ธˆ ์ƒ์†Œํ•œ ๊ฐœ๋…์ผ ์ˆ˜ ์žˆ๋‹ค.

Class Component

<Counter /> ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ž˜์Šค๋กœ ์ž‘์„ฑํ•œ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ๋‹ค.

class Counter extends Component {
    constructor(props) {
        super(props);
        this.state = {
            counter: 0
        }
        this.handleIncrease = this.handleIncrease.bind(this);
    }

    handleIncrease = () => {
        this.setState({
            counter: this.state.counter + 1
        })
    }

    render(){
       return (
            <div>
                <p>You clicked {this.state.counter} times</p>
                <button onClick={this.handleIncrease}>
                    Click me
                </button>
            </div>
       ) 
    }
}

'์ด๊ฒŒ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ผ๊ณ ?'๋ผ๊ณ  ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ
์ด์ „์˜ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋กœ ์ž‘์„ฑํ•  ๋•Œ์—๋Š” ์ด ์ •๋„๋Š” ์ž‘์„ฑ์„ ํ•ด์•ผ์ง€ ์•ฑ์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ด๋Ÿฐ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋Š” ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์›Œ์กŒ๊ณ , ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์—์„œ ์ƒํƒœ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์—ˆ๋‹ค. ๋˜ํ•œ React์˜ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” JavaScript์˜ this ํ‚ค์›Œ๋“œ๊ฐ€ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Š” ๋ฌธ๋ฒ•์„ ์ •ํ™•ํžˆ ์•Œ์ง€ ๋ชปํ•˜๋ฉด ๋™์ž‘ ๋ฐฉ์‹ ์ž์ฒด๋ฅผ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค๊ณค ํ–ˆ๋‹ค.

๊ทธ๋ž˜์„œ React๋Š” ์ ์ง„์ ์œผ๋กœ ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋„˜์–ด๊ฐ”๋‹ค. ๋‹ค๋งŒ ์ด์ „๊นŒ์ง€์˜ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ์ƒํƒœ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ๋“ค์ด ์กฐ๊ธˆ ๋ฏธ์ง„ํ–ˆ๋Š”๋ฐ, ๊ทธ ๋ถ€๋ถ„๋“ค์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด Hook์ด๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ•˜์˜€๋‹ค.


Function Component

์ด๋ฒˆ์—๋Š” <Counter /> ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋กœ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ๋‹ค.

function Counter () {
    const [counter, setCounter] = useState(0);

    const handleIncrease = () => {
        setCounter(counter + 1)
    }

    return (
        <div>
            <p>You clicked {counter} times</p>
            <button onClick={handleIncrease}>
                Click me
            </button>
        </div>
    )
}

ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์— ๋น„ํ•ด ํ›จ์”ฌ ๋” ์ง๊ด€์ ์ด๊ณ , ๋ณด๊ธฐ ์‰ฝ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

์ด Counter ์ปดํฌ๋„ŒํŠธ์—์„œ ์ˆซ์ž๋ฅผ ์˜ฌ๋ฆฌ๊ธฐ ์œ„ํ•ด ์ƒํƒœ๊ฐ’์„ ์ €์žฅํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š”
useState()๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๊ฒƒ์ด ์ตํžˆ ์•Œ๊ณ  ์žˆ๋Š” ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ”๋กœ Hook์ด๋‹ค.

๋‹ค์‹œ ๋งํ•˜์ž๋ฉด, Counter ์ปดํฌ๋„ŒํŠธ์—์„œ useState() Hook์„ ํ˜ธ์ถœํ•ด ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ(function component) ์•ˆ์— state๋ฅผ ์ถ”๊ฐ€ํ•œ ํ˜•ํƒœ์ด๋‹ค. ์ด state๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜์–ด๋„ ๊ทธ๋Œ€๋กœ ์œ ์ง€๋  ๊ฒƒ์ด๋‹ค. ๋˜ํ•œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์—์„œ State Hook์€ ํ•˜๋‚˜๋งŒ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ๋•Œ์— ๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ ๊ฐœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


Hook์ด๋ž€?

Hook์€ React 16.8์— ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ๊ธฐ๋Šฅ์ด๋‹ค.

Hook์€ class๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š๊ณ ๋„ state์™€ ๋‹ค๋ฅธ React์˜ ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

Hook์€ ๋‹ค๋ฅด๊ฒŒ ๋งํ•˜๋ฉด ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ ๊ฐ’ ๋ฐ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. Hook์€ class๊ฐ€ ์•„๋‹Œ function์œผ๋กœ๋งŒ React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šคํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

...
render(){
    /* ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋Š” render() ์•ˆ์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. */
    const [counter, setCounter] = useState(0);
...
}

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


Hook ์‚ฌ์šฉ ๊ทœ์น™

Hook์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‘ ๊ฐ€์ง€ ๊ทœ์น™์„ ์ค€์ˆ˜ํ•ด์•ผ๋งŒ ํ•œ๋‹ค.

1. ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜์˜ ์ตœ์ƒ์œ„์—์„œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ์‹คํ–‰ํ•˜๋ฉด ์˜ˆ์ƒํ•œ ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์„ ์šฐ๋ ค๊ฐ€ ์žˆ๋‹ค.

...
if(counter) {
    const [sample, setSample] = useState(0);
}
...


์˜ˆ๋ฅผ ๋“ค์–ด count๊ฐ€ ์žˆ์„ ๋•Œ sample์ด๋ผ๋Š” state๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ด์„œ ์กฐ๊ฑด๋ฌธ ์•ˆ์— useState() hook์„ ๋ถˆ๋Ÿฌ์™”๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. (์ด๋Ÿฐ ์‹์˜ ๊ฐ€์ •์€ ์• ์ดˆ๋ถ€ํ„ฐ ํ‹€๋ฆฐ ๊ฐ€์ •์ด๋‹ค.) ์ด๋Ÿฐ ์‹์œผ๋กœ ํ˜ธ์ถœ์„ ํ•˜๊ฒŒ ๋˜๋ฉด React์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๊ฑฐ์Šค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

์ปดํฌ๋„ŒํŠธ ์•ˆ์—๋Š” useState๋‚˜ useEffect ๊ฐ™์€ Hook๋“ค์ด ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋Š”๋ฐ,
React๋Š” ์ด Hook์„ ํ˜ธ์ถœ๋˜๋Š” ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅ์„ ํ•ด๋†“๋Š”๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์กฐ๊ฑด๋ฌธ, ๋ฐ˜๋ณต๋ฌธ ์•ˆ์—์„œ Hook์„ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด
ํ˜ธ์ถœ๋˜๋Š” ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅ์„ ํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง€๊ณ , ๊ฒฐ๊ตญ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๋ฒ„๊ทธ๋ฅผ ์ดˆ๋ž˜ํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ๋‹ค.

2. ์˜ค์ง ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค.

์ด๋Š” ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋‚˜ ์ปค์Šคํ…€ Hook์ด ์•„๋‹Œ
๋‹ค๋ฅธ ์ผ๋ฐ˜ JavaScript ํ•จ์ˆ˜ ์•ˆ์—์„œ ํ˜ธ์ถœํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

...
window.onload = function () {
    useEffect(() => {
        // do something...
    }, [counter]);
}
...


์˜ˆ๋ฅผ ๋“ค์–ด window์˜ ์š”์†Œ๊ฐ€ ๋ชจ๋‘ ์ค€๋น„๊ฐ€ ๋˜๋ฉด useEffect()๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. (์ด๋Ÿฐ ์‹์˜ ๊ฐ€์ •์€ ์• ์ดˆ๋ถ€ํ„ฐ ํ‹€๋ฆฐ ๊ฐ€์ •์ด๋‹ค.) ์ด ๋˜ํ•œ React์˜ ๋™์ž‘ ๋ฐฉ์‹์— ์œ„๋ฐฐ๋˜๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์—๋Ÿฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

์• ์ดˆ์— Hook์€ React์˜ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋„๋ก ๋งŒ๋“ค์–ด์ง„ ๋ฉ”์„œ๋“œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ทผ๋ณธ์ ์œผ๋กœ ์ผ๋ฐ˜ JavaScript ํ•จ์ˆ˜ ๋‚ด์—์„œ๋Š” ์ •์ƒ์ ์œผ๋กœ ๋Œ์•„๊ฐ€์ง€ ์•Š๋Š”๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๊ทœ์น™ ๋˜ํ•œ ๋ฐ˜๋“œ์‹œ ์ค€์ˆ˜ํ•ด์•ผ ํ•˜๋Š” ๊ทœ์น™์ด๋‹ค.



useMemo


์ปดํฌ๋„ŒํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜,
๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง์ด ๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜๋Š” ๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋„ˆ๋ฌด ์žฆ์€ ๋ฆฌ๋ Œ๋”๋ง์€ ์•ฑ์— ์ข‹์ง€ ์•Š์€ ์„ฑ๋Šฅ์„ ๋ผ์นœ๋‹ค.

React Hook์€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒํƒœ๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๋ฐ ์ตœ์ ํ™” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ๋” ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ผ๊ณ  ํ–ˆ๋‹ค. ๊ทธ์ค‘ ๋ Œ๋”๋ง ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ Hook๋„ ์กด์žฌํ•˜๋Š”๋ฐ, useCallback๊ณผ useMemo๊ฐ€ ๋ฐ”๋กœ ๊ทธ ์—ญํ• ์„ ํ•˜๋Š” Hook์ด๋‹ค.

useMemo๋ž€?

useMemo์€ ํŠน์ • ๊ฐ’(value)์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Hook์ด๋‹ค.

unction Calculator({value}){

	const result = calculate(value);

	return <>
      <div>
					{result}
      </div>
  </>;
}


ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” props๋กœ ๋„˜์–ด์˜จ value๊ฐ’์„ calculate๋ผ๋Š” ํ•จ์ˆ˜์—
์ธ์ž๋กœ ๋„˜๊ฒจ์„œ result ๊ฐ’์„ ๊ตฌํ•œ ํ›„, <div> ์—˜๋ฆฌ๋จผํŠธ๋กœ ์ถœ๋ ฅ์„ ํ•˜๊ณ  ์žˆ๋‹ค.

๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ calculate๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ณต์žกํ•œ ์—ฐ์‚ฐ์„ ํ•ด์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋ผ
๊ณ„์‚ฐ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ์— ์‹œ๊ฐ„์ด ๋ช‡ ์ดˆ ์ด์ƒ ๊ฑธ๋ฆฐ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด์ž.

๊ทธ๋ ‡๋‹ค๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง์„ ํ•  ๋•Œ๋งˆ๋‹ค ์ด ํ•จ์ˆ˜๋ฅผ
๊ณ„์†ํ•ด์„œ ํ˜ธ์ถœํ•  ๊ฒƒ์ด๊ณ , ๊ทธ๋•Œ๋งˆ๋‹ค ์‹œ๊ฐ„์ด ๋ช‡ ์ดˆ ์ด์ƒ ์†Œ์š”๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

์ด ๋ช‡ ์ดˆ์˜ ์ง€์—ฐ์€ ๋ Œ๋”๋ง์—๋„ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์ด๊ณ ,
์‚ฌ์šฉ์ž๋Š” โ€œ์•ฑ์˜ ๋กœ๋”ฉ ์†๋„๊ฐ€ ๋Š๋ฆฌ๋„ค?โ€๋ผ๋Š” ์ƒ๊ฐ์„ ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

/* useMemo๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์—๋Š” ๊ผญ importํ•ด์„œ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•œ๋‹ค. */
import { useMemo } from "react";

function Calculator({value}){

	const result = useMemo(() => calculate(value), [value]);

	return <>
      <div>
					{result}
      </div>
  </>;
}


์—ฌ๊ธฐ value๋ฅผ ์ธ์ž๋กœ ๋ฐ›๋Š” Calculator ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค.

value๋Š” ์ผ์ข…์˜ ๊ฐ’์œผ๋กœ์„œ, ์ด ๊ฐ’์ด ๊ณ„์† ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์–ด์ฉ” ์ˆ˜ ์—†๊ฒ ์ง€๋งŒ,
๋ Œ๋”๋ง์„ ํ•  ๋•Œ๋งˆ๋‹ค ์ด value๊ฐ’์ด ๊ณ„์† ๋ฐ”๋€Œ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•ด ๋ณด์ž.

๊ทธ๋Ÿผ ์ด ๊ฐ’์„ ์–ด๋”˜๊ฐ€์— ์ €์žฅ์„ ํ•ด๋’€๋‹ค๊ฐ€ ๋‹ค์‹œ ๊บผ๋‚ด์„œ ์“ธ ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด
๊ตณ์ด calculate ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ํ•„์š”๋„ ์—†์„ ๊ฒƒ์ด๋‹ค.

์—ฌ๊ธฐ์„œ useMemo Hook์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฐ ์‹์œผ๋กœ useMemo๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ calculate๋ฅผ ๊ฐ์‹ธ์ฃผ๋ฉด,
์ด์ „์— ๊ตฌ์ถ•๋œ ๋ Œ๋”๋ง๊ณผ ์ƒˆ๋กœ์ด ๊ตฌ์ถ•๋˜๋Š” ๋ Œ๋”๋ง์„ ๋น„๊ตํ•ด value๊ฐ’์ด ๋™์ผํ•  ๊ฒฝ์šฐ์—๋Š”
์ด์ „ ๋ Œ๋”๋ง์˜ value๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์žฌํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์ด๋Š” ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization) ๊ฐœ๋…๊ณผ ๊ธด๋ฐ€ํ•œ ๊ด€๊ณ„๊ฐ€ ์žˆ๋‹ค.


Memoization

๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization)์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์ž์ฃผ ๋‚˜์˜ค๋Š” ๊ฐœ๋…์ด๋‹ค.

๊ธฐ์กด์— ์ˆ˜ํ–‰ํ•œ ์—ฐ์‚ฐ์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ์„ ํ•ด๋‘๊ณ ,
๋™์ผํ•œ ์ž…๋ ฅ์ด ๋“ค์–ด์˜ค๋ฉด ์žฌํ™œ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ธฐ๋ฒ•์„ ๋งํ•œ๋‹ค.

์ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ตณ์ด ์ค‘๋ณต ์—ฐ์‚ฐ์„
ํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์•ฑ์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

useMemo๋Š” ๋ฐ”๋กœ ์ด ๊ฐœ๋…์„ ์ด์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ์—ฐ์‚ฐ์˜
์ค‘๋ณต์„ ํ”ผํ•˜๊ณ  React ์•ฑ์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”์‹œํ‚จ๋‹ค.

์ง์ ‘ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๊ฐœ๋…์„ ์ด์šฉํ•˜์—ฌ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์œผ๋‚˜,
useMemo Hook์„ ํ˜ธ์ถœํ•œ๋‹ค๋ฉด ์ด๋Ÿฐ ๋กœ์ง์„ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์„
๋Œ€์‹ ํ•ด ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํ›จ์”ฌ ๊ฐ„ํŽธํ•˜๋‹ค๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.


useMemo ์‹ค์Šต



ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ์ตœ์ ํ™”๋˜์ง€ ์•Š์€ ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.

์œ„์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‹ค์ œ๋กœ ์—ฐ์‚ฐ ๋กœ์ง์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๊ฐ’์€ val1๊ณผ val2์ด๋‹ค.

ํ˜„์žฌ๋Š” ์ด๋ฆ„ ์ƒํƒœ๊ฐ€ ๋ณ€ํ™”ํ•˜๋ฉด add ํ•จ์ˆ˜๊ฐ€ ๊ณ„์† ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฆฌํ„ดํ•จ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ 
๋ถˆํ•„์š”ํ•˜๊ฒŒ ๊ณ„์† ํ˜ธ์ถœ๋˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, useMemo๋ฅผ ์ด์šฉํ•˜์—ฌ addํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์„ ์ตœ์†Œํ™”ํ•ด์•ผ๋งŒ ํ•œ๋‹ค.

์ฆ‰, ์ด๋ฆ„์„ ์ž…๋ ฅํ•  ๋•Œ๋Š” add ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•„์•ผ ์ตœ์ ํ™”๊ฐ€ ๋œ ์ปดํฌ๋„ŒํŠธ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.



์œ„์˜ ์ฝ”๋“œ์—์„œ useMemo์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” add ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.

useMemo์˜ ๋‘ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด๋กœ, ์—ฌ๊ธฐ์— ํฌํ•จ๋œ ๊ฐ’๋“ค์ด ๋ณ€๊ฒฝ๋  ๋•Œ์—๋งŒ
์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ด์ „์— ๊ณ„์‚ฐํ•œ ๊ฐ’์„ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด val1๊ณผ val2๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งŒ add ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ ,
name๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ๋ถˆํ•„์š”ํ•œ ํ˜ธ์ถœ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ด๋กœ ์ธํ•ด ์ปดํฌ๋„ŒํŠธ์˜ ์ตœ์ ํ™”๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค.



useCallback


useCallback ๋˜ํ•œ useMemo์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ๊ธฐ๋ฒ•์„ ์ด์šฉํ•œ Hook์ด๋‹ค.

useMemo๋Š” ๊ฐ’์˜ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” Hook์ด๋ผ๋ฉด,
useCallback์€ ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” Hook์ด๋‹ค.

function Calculator({x, y}){

	const add = () => x + y;

	return <>
      <div>
					{add()}
      </div>
  </>;
}


ํ˜„์žฌ ์ด Calculator ์ปดํฌ๋„ŒํŠธ ๋‚ด์—๋Š” add๋ผ๋Š” ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ์ด ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์ด๋‹ค.

์ด add ํ•จ์ˆ˜๋Š” props๋กœ ๋„˜์–ด์˜จ x์™€ y ๊ฐ’์„ ๋”ํ•ด <div> ํƒœ๊ทธ์— ๊ฐ’์„ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ๋‹ค.
์ด ํ•จ์ˆ˜๋Š” ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กญ๊ฒŒ ๋งŒ๋“ค์–ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

useMemo์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋˜๋”๋ผ๋„ ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๊ฐ’์ธ x์™€ y๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์ž. ๊ทธ๋ ‡๋‹ค๋ฉด ํ•จ์ˆ˜ ๋˜ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์–ด๋”˜๊ฐ€์— ์ €์žฅํ•ด ๋’€๋‹ค๊ฐ€ ๋‹ค์‹œ ๊บผ๋‚ด์„œ ์“ธ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

์ด๋•Œ useCallback Hook์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ ํ•จ์ˆ˜๊ฐ€ ์˜์กดํ•˜๋Š” ๊ฐ’๋“ค์ด
๋ฐ”๋€Œ์ง€ ์•Š๋Š” ํ•œ ๊ธฐ์กด ํ•จ์ˆ˜๋ฅผ ๊ณ„์†ํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ฆ‰ x์™€ y๊ฐ’์ด ๋™์ผํ•˜๋‹ค๋ฉด ๋‹ค์Œ ๋ Œ๋”๋ง ๋•Œ ์ด ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•œ๋‹ค.

/* useCallback๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์—๋Š” ๊ผญ importํ•ด์„œ ๋ถˆ๋Ÿฌ์™€์•ผ ํ•œ๋‹ค. */
import React, { useCallback } from "react";

function Calculator({x, y}){

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

	return <>
      <div>
					{add()}
      </div>
  </>;
}


์‚ฌ์‹ค useCallback๋งŒ ์‚ฌ์šฉํ•ด์„œ๋Š” useMemo์— ๋น„ํ•ด ๊ด„๋ชฉํ•  ๋งŒํ•œ ์ตœ์ ํ™”๋ฅผ ๋Š๋‚„ ์ˆ˜๋Š” ์—†๋‹ค.

์™œ๋ƒํ•˜๋ฉด useCallback์€ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœ์„ ํ•˜์ง€ ์•Š๋Š” Hook์ด ์•„๋‹ˆ๋ผ,
๊ทธ์ € ๋ฉ”๋ชจ๋ฆฌ ์–ด๋”˜๊ฐ€์— ํ•จ์ˆ˜๋ฅผ ๊บผ๋‚ด์„œ ํ˜ธ์ถœํ•˜๋Š” Hook์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋”ฐ๋ผ์„œ ๋‹จ์ˆœํžˆ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ
useCallback์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ํฐ ์˜๋ฏธ๊ฐ€ ์—†๊ฑฐ๋‚˜ ์˜คํžˆ๋ ค ์†ํ•ด์ธ ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด ์–ธ์ œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์ข‹์„๊นŒ?

์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ props๋กœ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•ด ์ค„ ๋•Œ ์ด useCallback์„ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์ข‹๋‹ค.


useCallback๊ณผ ์ฐธ์กฐ ๋™๋“ฑ์„ฑ

useCallback์€ ์ฐธ์กฐ ๋™๋“ฑ์„ฑ์— ์˜์กดํ•œ๋‹ค. React๋Š” JavaScript ์–ธ์–ด๋กœ ๋งŒ๋“ค์–ด์ง„ ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋กœ JavaScript์˜ ๋ฌธ๋ฒ•์„ ๋”ฐ๋ผ๊ฐ„๋‹ค. JavaScript์—์„œ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ด๋‹ค. ๊ฐ์ฒด๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•  ๋•Œ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ๊ฐ’์˜ ์ฃผ์†Œ๋ฅผ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์ด ๊ฐ™์„์ง€๋ผ๋„ ์ผ์น˜์—ฐ์‚ฐ์ž๋กœ ๋น„๊ตํ–ˆ์„ ๋•Œ false๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

function doubleFactory(){
    return (a) => 2 * a;
}
  
const double1 = doubleFactory();
const double2 = doubleFactory();
  
double1(8); // 16
double2(8); // 16
  
double1 === double2;  // false
double1 === double1;  // true


double1๊ณผ double2๋Š” ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ–ˆ์Œ์—๋„ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ๊ฐ’์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™๋‹ค๊ณ  ๋ณด์ง€ ์•Š๋Š”๋‹ค. JavaScript์—์„œ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ด๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ๊ฐœ์˜ ํ•จ์ˆ˜๋Š” ๋™์ผํ•œ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•˜๋”๋ผ๋„ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์— ์˜ํ•œ ์ฐธ์กฐ ๋น„๊ต ์‹œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋กœ ๋ณธ๋‹ค.

์ด๋Š” React ๋˜ํ•œ ๊ฐ™๋‹ค. React๋Š” ๋ฆฌ๋ Œ๋”๋ง ์‹œ ํ•จ์ˆ˜๋ฅผ ์ƒˆ๋กœ์ด ๋งŒ๋“ค์–ด์„œ ํ˜ธ์ถœ์„ ํ•œ๋‹ค. ์ƒˆ๋กœ์ด ๋งŒ๋“ค์–ด ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜๋Š” ๊ธฐ์กด์˜ ํ•จ์ˆ˜์™€ ๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ useCallback์„ ์ด์šฉํ•ด ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ์ €์žฅํ•ด์„œ ๋‹ค์‹œ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜์˜ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ ๊ฐ’์„ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋‹ค์‹œ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ React ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ธฐ๊ฑฐ๋‚˜ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ prop์œผ๋กœ ๋„˜๊ธธ ๋•Œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.


useCallback ์‹ค์Šต



input ์ฐฝ์— ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด๋ณด์ž. ๊ทธ๋Ÿฌ๋ฉด ์ฝ˜์†”์— โ€œ์•„์ดํ…œ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.โ€ ๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์ด ๋ณด์ผ ๊ฒƒ์ด๋‹ค.

์ •์ƒ์ ์ธ ๋™์ž‘์ด์ง€๋งŒ, ์ด๋ฒˆ์—๋Š” ์˜†์˜ button dark mode๋„ ๋ˆŒ๋Ÿฌ๋ณด์ž.
button์„ ๋ˆŒ๋Ÿฌ๋„ โ€œ์•„์ดํ…œ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.โ€๊ฐ€ ์ฝ˜์†”์— ์ถœ๋ ฅ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์™œ ์ด๋ ‡๊ฒŒ ๋™์ž‘ํ• ๊นŒ? ์ด ๋™์ž‘์˜ ์ด์œ ๋Š” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ๋„ ์•ฑ์ด ๋ฆฌ๋ Œ๋”๋ง ๋˜๋ฏ€๋กœ, App ๋‚ด๋ถ€์˜ getItems() ํ•จ์ˆ˜๊ฐ€ ๋‹ค์‹œ ๋งŒ๋“ค์–ด์ง„๋‹ค. ์ƒˆ๋กœ์ด ๋งŒ๋“ค์–ด์ง„ ํ•จ์ˆ˜๋Š” ์ด์ „์˜ ํ•จ์ˆ˜์™€ ์ฐธ์กฐ ๋น„๊ต ์‹œ ๋‹ค๋ฅธ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— List ๊ตฌ์„ฑ ์š”์†Œ ๋‚ด์—์„œ useEffect Hook์€ setItems๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ข…์†์„ฑ์ด ๋ณ€๊ฒฝ๋จ์— ๋”ฐ๋ผ โ€œ์•„์ดํ…œ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.โ€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค.



useCallback์„ ์‚ฌ์šฉํ•˜์—ฌ getItems ํ•จ์ˆ˜๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜๋ฉด,
input ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ด์ „์— ์ƒ์„ฑ๋œ ํ•จ์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.



Custom Hooks


๊ฐœ๋ฐœ์ž๊ฐ€ ์Šค์Šค๋กœ ์ปค์Šคํ…€ํ•œ ํ›…์„ ์˜๋ฏธํ•˜๋ฉฐ ์ด๋ฅผ ์ด์šฉํ•ด ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง์„ ํ•จ์ˆ˜๋กœ ๋ฝ‘์•„๋‚ด์–ด ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๋Ÿฌ url์„ fetchํ•  ๋•Œ, ์—ฌ๋Ÿฌ input์— ์˜ํ•œ ์ƒํƒœ ๋ณ€๊ฒฝ ๋“ฑ
๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง์„ ๋™์ผํ•œ ํ•จ์ˆ˜์—์„œ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์ปค์Šคํ…€ ํ›…์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

์ด๋ฅผ ์ด์šฉํ•˜๋ฉด

  1. ์ƒํƒœ๊ด€๋ฆฌ ๋กœ์ง์˜ ์žฌํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•˜๊ณ 

  2. ํด๋ž˜์Šค ์ปดํฌ๋„ŒํŠธ๋ณด๋‹ค ์ ์€ ์–‘์˜ ์ฝ”๋“œ๋กœ ๋™์ผํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ

  3. ํ•จ์ˆ˜ํ˜•์œผ๋กœ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด๋‹ค ๋ช…๋ฃŒํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค. (e.g. useSomething)

//FriendStatus : ์นœ๊ตฌ๊ฐ€ online์ธ์ง€ offline์ธ์ง€ returnํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ
function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

//FriendListItem : ์นœ๊ตฌ๊ฐ€ online์ผ ๋•Œ ์ดˆ๋ก์ƒ‰์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ
function FriendListItem(props) {
  const [isOnline, setIsOnline] = useState(null);
  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}


FriendStatus ์ปดํฌ๋„ŒํŠธ๋Š” ์‚ฌ์šฉ์ž๋“ค์ด ์˜จ๋ผ์ธ์ธ์ง€ ์˜คํ”„๋ผ์ธ์ธ์ง€ ํ™•์ธํ•˜๊ณ ,
FriendListItem ์ปดํฌ๋„ŒํŠธ๋Š” ์‚ฌ์šฉ์ž๋“ค์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ์˜จ๋ผ์ธ์ด๋ผ๋ฉด ์ดˆ๋ก์ƒ‰์œผ๋กœ ํ‘œ์‹œํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.

์ด ๋‘ ์ปดํฌ๋„ŒํŠธ๋Š” ์ •ํ™•ํ•˜๊ฒŒ ๋˜‘๊ฐ™์ด ์“ฐ์ด๋Š” ๋กœ์ง์ด ์กด์žฌํ•˜๊ณ  ์žˆ๋‹ค.

์ด ๋กœ์ง์„ ๋นผ๋‚ด์„œ ๋‘ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ณต์œ ํ•  ์ˆ˜๋Š” ์—†์„๊นŒ?
Custom Hook์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค.

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
    };
  });

  return isOnline;
}


๋‘ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋™์ผํ•˜๊ฒŒ
์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ํ•จ์ˆ˜ useFriendStatus๋กœ ๋งŒ๋“ ๋‹ค.

์ด๋ ‡๊ฒŒ Custom Hook์„ ์ •์˜ํ•  ๋•Œ๋Š” ์ผ์ข…์˜ ๊ทœ์น™์ด ํ•„์š”ํ•˜๋‹ค.

  • Custom Hook์„ ์ •์˜ํ•  ๋•Œ๋Š” ํ•จ์ˆ˜ ์ด๋ฆ„ ์•ž์— use๋ฅผ ๋ถ™์ด๋Š” ๊ฒƒ์ด ๊ทœ์น™์ด๋‹ค.
  • ๋Œ€๊ฐœ์˜ ๊ฒฝ์šฐ ํ”„๋กœ์ ํŠธ ๋‚ด์˜ hooks ๋””๋ ‰ํ† ๋ฆฌ์— Custom Hook์„ ์œ„์น˜์‹œํ‚จ๋‹ค.
  • Custom Hook์œผ๋กœ ๋งŒ๋“ค ๋•Œ ํ•จ์ˆ˜๋Š” ์กฐ๊ฑด๋ถ€ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰ return ํ•˜๋Š” ๊ฐ’์€ ์กฐ๊ฑด๋ถ€์—ฌ์„œ๋Š” ์•ˆ ๋œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ ์ด useFriendStatus Hook์€ ์˜จ๋ผ์ธ ์ƒํƒœ์˜ ์—ฌ๋ถ€๋ฅผ boolean ํƒ€์ž…์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ Custom Hook์€ Hook ๋‚ด๋ถ€์—
useState์™€ ๊ฐ™์€ React ๋‚ด์žฅ Hook์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

์ผ๋ฐ˜ ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋Š” React ๋‚ด์žฅ Hook์„ ๋ถˆ๋Ÿฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์ง€๋งŒ,
Custom Hook์—์„œ๋Š” ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ ๋˜ํ•œ ์•Œ์•„๋‘๋ฉด ์ข‹์„ ์ ์ด๋‹ค.

์ด์ œ ์ด useFriendStatus Hook์„ ๋‘ ์ปดํฌ๋„ŒํŠธ์— ์ ์šฉํ•ด ๋ณด๊ฒ ๋‹ค.

function FriendStatus(props) {
  const isOnline = useFriendStatus(props.friend.id);

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

function FriendListItem(props) {
  const isOnline = useFriendStatus(props.friend.id);

  return (
    <li style={{ color: isOnline ? 'green' : 'black' }}>
      {props.friend.name}
    </li>
  );
}


๋กœ์ง์„ ๋ถ„๋ฆฌํ•ด Custom Hook์œผ๋กœ ๋งŒ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ ์ปดํฌ๋„ŒํŠธ๋Š” ๋” ์ง๊ด€์ ์œผ๋กœ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ฐ™์€ Custom Hook์„ ์‚ฌ์šฉํ–ˆ๋‹ค๊ณ  ํ•ด์„œ
๋‘ ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ™์€ state๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

๊ทธ์ € ๋กœ์ง๋งŒ ๊ณต์œ ํ•  ๋ฟ, state๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๋‹ค.


Custom Hook์˜ ์˜ˆ์‹œ

// ์—ฌ๋Ÿฌ url์„ fetchํ•  ๋•Œ ์“ธ ์ˆ˜ ์žˆ๋Š” useFetch Hook

const useFetch = ( initialUrl:string ) => {
	const [url, setUrl] = useState(initialUrl);
	const [value, setValue] = useState('');

	const fetchData = () => axios.get(url).then(({data}) => setValue(data));	

	useEffect(() => {
		fetchData();
	},[url]);

	return [value];
};

export default useFetch;
// ์—ฌ๋Ÿฌ input์— ์˜ํ•œ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ•  ๋•Œ ์“ธ ์ˆ˜ ์žˆ๋Š” useInputs Hooks

import { useState, useCallback } from 'react';

function useInputs(initialForm) {
  const [form, setForm] = useState(initialForm);
  // change
  const onChange = useCallback(e => {
    const { name, value } = e.target;
    setForm(form => ({ ...form, [name]: value }));
  }, []);
  const reset = useCallback(() => setForm(initialForm), [initialForm]);
  return [form, onChange, reset];
}

export default useInputs;


Custom Hooks ์‹ค์Šต


custom hook์„ ์ด์šฉํ•˜์—ฌ useEffect ๋กœ์ง ๋ถ„๋ฆฌํ•˜๊ธฐ



useEffect hook์„ ์ด์šฉํ•œ ๋กœ์ง์€ ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง์ด ๋งŽ๋‹ค.
ํŠนํžˆ API๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์€ ๋ฐ˜๋ณต์ ์ผ ์ˆ˜๋ฐ–์— ์—†๋‹ค.

์ด๋Ÿฌํ•œ ๋กœ์ง์„ custom hook์œผ๋กœ ๋งŒ๋“ค์–ด ๋ถ„๋ฆฌํ•˜๊ณ  ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค
์ ์šฉ์„ ํ•œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์ข€ ๋” ์ง๊ด€์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

App ์ปดํฌ๋„ŒํŠธ์— ๋“ค์–ด์žˆ๋Š” useEffect hook ๋กœ์ง์„ util ํด๋” ๋‚ด์˜
hooks.js ํŒŒ์ผ์— ๋ถ„๋ฆฌํ•ด ๋ณด๊ณ , ์ง๊ด€์ ์œผ๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋„๋ก hooks.js์˜ ์ด๋ฆ„๋„ ๋ณ€๊ฒฝํ•ด๋ณด์ž.



useEffect ๋กœ์ง์ด useFetchData๋ผ๋Š” custom hook์œผ๋กœ ๋ถ„๋ฆฌ๋˜์—ˆ๋‹ค.

App ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ํ•„์š”ํ•œ URL์„ ์ „๋‹ฌํ•˜๋ฉด custom hook์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š”
๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๊ณ , App ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ์—ญํ• ์„ ํ•˜๊ฒŒ ๋œ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งˆ๋‹ค custom hook์„ ์ ์šฉํ•จ์œผ๋กœ์จ
๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ , ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ํ–ฅ์ƒ๋œ๋‹ค.


custom hook์„ ์ด์šฉํ•˜์—ฌ input ๋กœ์ง ๋ถ„๋ฆฌํ•˜๊ธฐ



input ๋˜ํ•œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋กœ์ง์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค. ์ด๋Ÿฐ ์‹์œผ๋กœ ์•ฑ ๋‚ด์— ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ๊ด€๋ฆฌ๋˜๋Š” ๋กœ์ง์€ ๋งŽ๋‹ค. (input, form, button ๋“ฑ) input๋„ ์ง€๊ธˆ์€ 2๊ฐœ ์ •๋„ ์žˆ์–ด ๊ด€๋ฆฌ๊ฐ€ ํฌ๊ฒŒ ์š”๊ตฌ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ›„์— ํšŒ์›๊ฐ€์ž… ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜, ์•ฑ์˜ ๋ณผ๋ฅจ์ด ์ปค์ง€๊ฒŒ ๋œ๋‹ค๋ฉด input์€ ๊ต‰์žฅํžˆ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” UI ์ค‘ ํ•˜๋‚˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง์„ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ํ•„์š”์„ฑ์ด ์ƒ๊ธด๋‹ค. ์ด๋Ÿฐ ์ปดํฌ๋„ŒํŠธ ๋˜ํ•œ custom hook์„ ์ด์šฉํ•˜์—ฌ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปดํฌ๋„ŒํŠธ ๋‚ด์— ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง์„ ๋ถ„๋ฆฌ๋ฅผ ํ•ด ๊ด€๋ฆฌ๋ฅผ ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์ข€ ๋” ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

App ์ปดํฌ๋„ŒํŠธ์— ๋“ค์–ด ์žˆ๋Š” input์„ Input ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฐ”๊พผ ํ›„,
custom hook์„ ์ด์šฉํ•˜์—ฌ input์˜ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•ด๋ณด์ž.



์œ„์™€ ๊ฐ™์ด Input ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๊ณ ,
useInput custom hook์„ ์‚ฌ์šฉํ•˜์—ฌ input ๊ด€๋ จ ๋กœ์ง์„ ๋ถ„๋ฆฌํ–ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด input ๊ด€๋ จ ๋กœ์ง์„ ๋ณ„๋„์˜ ์ปดํฌ๋„ŒํŠธ์™€ custom hook์œผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

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

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

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