์ด๋ฒ ์ ๋์์๋ ๋ฆฌ์กํธ์ ๋์ ๋ฐฉ์๊ณผ, ๋ฆฌ์กํธ Hooks์ ๋ํด ๋ฐฐ์ฐ๋ฉฐ ๋ฆฌ์กํธ๋ฅผ ์ข ๋ ์ฌ๋ ์๊ฒ ํ์ตํ๋ค.
๋ฆฌ์กํธ์ ๋์ ๋ฐฉ์๊ณผ, ๋ฆฌ์กํธ Hooks์ ๋ํด ํ์ตํ์ ๋ค๋ฉด ๋์ฑ ๋ฉ์ง ์ฑ์ ๋ง๋ค ์ ์์ ๊ฒ์ด๋ค.
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 ์กฐ์์ ์ต์ํํ๋ ๊ฒ์ด ์ฑ๋ฅ ์ต์ ํ์ ํต์ฌ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค.
React๊ฐ ๊ธฐ์กด ๊ฐ์ DOM๊ณผ ๋ณ๊ฒฝ๋ ์๋ก์ด ๊ฐ์ DOM์ ๋น๊ตํ ๋, React ์ ์ฅ์์๋ ๋ณ๊ฒฝ๋ ์๋ก์ด ๊ฐ์ DOM ํธ๋ฆฌ์ ๋ถํฉํ๋๋ก ๊ธฐ์กด์ UI๋ฅผ ํจ์จ์ ์ผ๋ก ๊ฐฑ์ ํ๋ ๋ฐฉ๋ฒ์ ์์๋ผ ํ์๊ฐ ์์๋ค.
์ฆ ํ๋์ ํธ๋ฆฌ๋ฅผ ๋ค๋ฅธ ํธ๋ฆฌ๋ก ๋ณํ์ ์ํค๋ ๊ฐ์ฅ ์์ ์กฐ์ ๋ฐฉ์์ ์์๋ด์ผ๋ง ํ๋๋ฐ,
์์๋ธ ์กฐ์ ๋ฐฉ์ ์๊ณ ๋ฆฌ์ฆ์ O(n^3)์ ๋ณต์ก๋๋ฅผ ๊ฐ์ง๊ณ ์์๋ค.
๋ง์ฝ ์ด ์๊ณ ๋ฆฌ์ฆ์ ๊ทธ๋๋ก React์ ์ ์ฉํ๋ค๋ฉด 1000๊ฐ์ ์๋ฆฌ๋จผํธ๋ฅผ ์ค์ ํ๋ฉด์ ํ์ํ๊ธฐ ์ํด 10์ต(1000^3)๋ฒ์ ๋น๊ต ์ฐ์ฐ์ ํด์ผ๋ง ํ๋ค. ์ฌ์ค ์ด๊ฒ์ ๋๋ฌด ๋น์ผ ์ฐ์ฐ์ด๊ธฐ ๋๋ฌธ์ React๋ ๋ ๊ฐ์ง์ ๊ฐ์ ์ ๊ฐ์ง๊ณ ์๊ฐ ๋ณต์ก๋ O(n)์ ์๋ก์ด ํด๋ฆฌ์คํฑ ์๊ณ ๋ฆฌ์ฆ(Heuristic Algorithm)์ ๊ตฌํํด ๋ธ๋ค.
๋ ๊ฐ์ง ๊ฐ์ ์ ์ด๊ฒ์ด๋ค.
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 ํธ๋ฆฌ๋ฅผ ๊ตฌ์ถํด ๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ ๋นํจ์จ์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ด๋ค.
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 ํจ์ ๋ด์์๋ ์ ์์ ์ผ๋ก ๋์๊ฐ์ง ์๋๋ค. ๋ฐ๋ผ์ ์ด ๊ท์น ๋ํ ๋ฐ๋์ ์ค์ํด์ผ ํ๋ ๊ท์น์ด๋ค.
์ปดํฌ๋ํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ํ๊ฐ ๋ณ๊ฒฝ๋๊ฑฐ๋,
๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง์ด ๋ ๋๋ง๋ค ๋ฆฌ๋ ๋๋ง์ ํ๋ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
๊ทธ๋ฌ๋ ๋๋ฌด ์ฆ์ ๋ฆฌ๋ ๋๋ง์ ์ฑ์ ์ข์ง ์์ ์ฑ๋ฅ์ ๋ผ์น๋ค.
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์ ํธ์ถํ๋ค๋ฉด ์ด๋ฐ ๋ก์ง์ ์ง์ ๊ตฌํํ๋ ๊ฒ์
๋์ ํด ์ฃผ๊ธฐ ๋๋ฌธ์ ํจ์ฌ ๊ฐํธํ๋ค๊ณ ํ ์ ์๋ค.
ํด๋น ์ปดํฌ๋ํธ๋ ์์ง ์ต์ ํ๋์ง ์์ ์ปดํฌ๋ํธ์ด๋ค.
์์ ์ปดํฌ๋ํธ์์ ์ค์ ๋ก ์ฐ์ฐ ๋ก์ง์ ์ํฅ์ ์ฃผ๋ ๊ฐ์ val1๊ณผ val2์ด๋ค.
ํ์ฌ๋ ์ด๋ฆ ์ํ๊ฐ ๋ณํํ๋ฉด add ํจ์๊ฐ ๊ณ์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฆฌํดํจ์๋ ๋ถ๊ตฌํ๊ณ
๋ถํ์ํ๊ฒ ๊ณ์ ํธ์ถ๋๊ณ ์๊ธฐ ๋๋ฌธ์, useMemo๋ฅผ ์ด์ฉํ์ฌ addํจ์์ ํธ์ถ์ ์ต์ํํด์ผ๋ง ํ๋ค.
์ฆ, ์ด๋ฆ์ ์ ๋ ฅํ ๋๋ add ํจ์๊ฐ ํธ์ถ๋์ง ์์์ผ ์ต์ ํ๊ฐ ๋ ์ปดํฌ๋ํธ๋ผ๊ณ ๋ณผ ์ ์๋ค.
์์ ์ฝ๋์์ useMemo์ ์ฝ๋ฐฑ ํจ์๋ add ํจ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๋ถ๋ถ์ด๋ค.
useMemo์ ๋ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ ์์กด์ฑ ๋ฐฐ์ด๋ก, ์ฌ๊ธฐ์ ํฌํจ๋ ๊ฐ๋ค์ด ๋ณ๊ฒฝ๋ ๋์๋ง
์ฝ๋ฐฑ ํจ์๋ฅผ ํธ์ถํ๊ณ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ด์ ์ ๊ณ์ฐํ ๊ฐ์ ์ฌ์ฉํ๋ค.
์ด๋ ๊ฒ ํ๋ฉด val1๊ณผ val2๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง add ํจ์๊ฐ ํธ์ถ๋๊ณ ,
name๊ณผ ๊ฐ์ ๋ค๋ฅธ ์ํ๊ฐ ๋ณ๊ฒฝ๋์ด๋ ๋ถํ์ํ ํธ์ถ์ด ๋ฐ์ํ์ง ์๋๋ค.
์ด๋ก ์ธํด ์ปดํฌ๋ํธ์ ์ต์ ํ๊ฐ ์ด๋ฃจ์ด์ง๋ค.
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์ผ๋ก ๋๊ธธ ๋ ์์์น ๋ชปํ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ๋ง์ ์ ์๋ค.
input
์ฐฝ์ ์ซ์๋ฅผ ์
๋ ฅํด๋ณด์. ๊ทธ๋ฌ๋ฉด ์ฝ์์ โ์์ดํ
์ ๊ฐ์ ธ์ต๋๋ค.โ ๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ด ๋ณด์ผ ๊ฒ์ด๋ค.
์ ์์ ์ธ ๋์์ด์ง๋ง, ์ด๋ฒ์๋ ์์ button dark mode๋ ๋๋ฌ๋ณด์.
button์ ๋๋ฌ๋ โ์์ดํ
์ ๊ฐ์ ธ์ต๋๋ค.โ๊ฐ ์ฝ์์ ์ถ๋ ฅ๋๋ ๊ฑธ ๋ณผ ์ ์๋ค.
์ ์ด๋ ๊ฒ ๋์ํ ๊น? ์ด ๋์์ ์ด์ ๋ ๋ฒํผ์ ๋๋ฅผ ๋๋ ์ฑ์ด ๋ฆฌ๋ ๋๋ง ๋๋ฏ๋ก, App ๋ด๋ถ์ getItems()
ํจ์๊ฐ ๋ค์ ๋ง๋ค์ด์ง๋ค. ์๋ก์ด ๋ง๋ค์ด์ง ํจ์๋ ์ด์ ์ ํจ์์ ์ฐธ์กฐ ๋น๊ต ์ ๋ค๋ฅธ ํจ์์ด๊ธฐ ๋๋ฌธ์ List ๊ตฌ์ฑ ์์ ๋ด์์ useEffect
Hook์ setItems
๋ฅผ ํธ์ถํ๊ณ ์ข
์์ฑ์ด ๋ณ๊ฒฝ๋จ์ ๋ฐ๋ผ โ์์ดํ
์ ๊ฐ์ ธ์ต๋๋ค.โ๋ฅผ ์ถ๋ ฅํ๋ ๊ฒ์ด๋ค.
useCallback
์ ์ฌ์ฉํ์ฌ getItems
ํจ์๋ฅผ ๋ฉ๋ชจ์ด์ ์ด์
ํ๋ฉด,
input
์ํ๊ฐ ๋ณ๊ฒฝ๋์ด๋ ์ด์ ์ ์์ฑ๋ ํจ์๋ฅผ ์ฌ์ฌ์ฉํ๊ฒ ๋๋ค.
๊ฐ๋ฐ์๊ฐ ์ค์ค๋ก ์ปค์คํ ํ ํ ์ ์๋ฏธํ๋ฉฐ ์ด๋ฅผ ์ด์ฉํด ๋ฐ๋ณต๋๋ ๋ก์ง์ ํจ์๋ก ๋ฝ์๋ด์ด ์ฌ์ฌ์ฉํ ์ ์๋ค.
์ฌ๋ฌ url์ fetchํ ๋, ์ฌ๋ฌ input์ ์ํ ์ํ ๋ณ๊ฒฝ ๋ฑ
๋ฐ๋ณต๋๋ ๋ก์ง์ ๋์ผํ ํจ์์์ ์๋ํ๊ฒ ํ๊ณ ์ถ์ ๋ ์ปค์คํ
ํ
์ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
์ด๋ฅผ ์ด์ฉํ๋ฉด
์ํ๊ด๋ฆฌ ๋ก์ง์ ์ฌํ์ฉ์ด ๊ฐ๋ฅํ๊ณ
ํด๋์ค ์ปดํฌ๋ํธ๋ณด๋ค ์ ์ ์์ ์ฝ๋๋ก ๋์ผํ ๋ก์ง์ ๊ตฌํํ ์ ์์ผ๋ฉฐ
ํจ์ํ์ผ๋ก ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ณด๋ค ๋ช
๋ฃํ๋ค๋ ์ฅ์ ์ด ์๋ค. (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์ ์ ์ํ ๋๋ ์ผ์ข ์ ๊ท์น์ด ํ์ํ๋ค.
use
๋ฅผ ๋ถ์ด๋ ๊ฒ์ด ๊ท์น์ด๋ค.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 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
๊ณผ ๊ด๋ จ๋ ๋ก์ง์ ๋ณด๋ค
๊น๋ํ๊ฒ ์ ์งํ ์ ์์ผ๋ฉฐ, ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ๊ณผ ๊ด๋ฆฌ์ฑ์ด ๋์ฑ ํฅ์๋๋ค.