React์ DOM์ ๋ํด์
Virtual DOM์ด๋?
Virtual DOM์ ์ค์ DOM์ ๊ฐ๋ฒผ์ด ๋ณต์ฌ๋ณธ์ผ๋ก, ๋ฉ๋ชจ๋ฆฌ์ ์กด์ฌํ๋ JavaScript ๊ฐ์ฒด์ด๋ค. React๊ฐ UI ์ ๋ฐ์ดํธ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉํ๋ ํต์ฌ ๊ฐ๋ ์ด๋ค.
Virtual DOM์ ์๋ ๋ฐฉ์
State ๋ณ๊ฒฝ ๊ฐ์ง
- ์ปดํฌ๋ํธ์ state๋ props๊ฐ ๋ณ๊ฒฝ๋๋ฉด React๋ ์๋ก์ด Virtual DOM ํธ๋ฆฌ๋ฅผ ์์ฑํ๋ค.
Diffing ์๊ณ ๋ฆฌ์ฆ
- ์ด์ Virtual DOM๊ณผ ์๋ก์ด Virtual DOM์ ๋น๊ตํ๋ค.
- ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง์ ์ฐพ์๋ด๋ ๊ณผ์ ์ "์ฌ์กฐ์ (Reconciliation)"์ด๋ผ๊ณ ํ๋ค.
๋ฐฐ์น ์ ๋ฐ์ดํธ
- ์ฐพ์๋ธ ์ฐจ์ด์ ๋ค์ ๋ชจ์์ ์ค์ DOM์ ํ ๋ฒ์ ์ ์ฉํ๋ค.
- ์ด๋ฅผ ํตํด ๋ถํ์ํ DOM ์กฐ์์ ์ต์ํํ๋ค.
Virtual DOM์ ์ฅ์
์ฑ๋ฅ ์ต์ ํ
// ์์: ์ฌ๋ฌ ์ํ ์ ๋ฐ์ดํธ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌ function Counter() { const [count, setCount] = useState(0); return ( <div> <h1>{count}</h1> <button onClick={() => setCount(count + 1)}>์ฆ๊ฐ</button> </div> ); }ํฌ๋ก์ค ํ๋ซํผ ์ง์
- DOM์ด ์๋ ํ๊ฒฝ(์: React Native)์์๋ ๋์ผํ ๊ฐ๋ ์ ์ฉ ๊ฐ๋ฅ
- ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง ์ง์
๊ฐ๋ฐ ๊ฒฝํ ํฅ์
- ์ ์ธ์ UI ํ๋ก๊ทธ๋๋ฐ ๊ฐ๋ฅ
- ์ํ ๊ด๋ฆฌ ๋จ์ํ
์ต์ ํ ๊ธฐ๋ฒ
์ปดํฌ๋ํธ ๋ฉ๋ชจ์ด์ ์ด์
// React.memo๋ก ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง ๋ฐฉ์ง const MemoizedComponent = React.memo(function MyComponent(props) { return <div>{props.value}</div>; });Hook์ ํ์ฉํ ์ต์ ํ
// useMemo๋ก ๊ณ์ฐ ๋น์ฉ์ด ํฐ ๊ฐ ๋ฉ๋ชจ์ด์ ์ด์ const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); // useCallback์ผ๋ก ํจ์ ๋ฉ๋ชจ์ด์ ์ด์ const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);
์ฃผ์์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
ํค(Key) ์์ฑ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๊ธฐ
// ์ข์ ์์ { items.map((item) => <ListItem key={item.id} {...item} />); }์ํ ์ ๋ฐ์ดํธ๋ ๋ถ๋ณ์ฑ ์ ์งํ๊ธฐ
// ์๋ชป๋ ๋ฐฉ๋ฒ const [items, setItems] = useState([]); items.push(newItem); // // ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ setItems([...items, newItem]); //ํฐ ๋ฆฌ์คํธ๋ ๊ฐ์ํ ์ฌ์ฉํ๊ธฐ
- react-window๋ react-virtualized ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ
๊ฒฐ๋ก
Virtual DOM์ React์ ํต์ฌ ๊ธฐ๋ฅ ์ค ํ๋๋ก, ๋ณต์กํ UI ์ ๋ฐ์ดํธ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ํด์ค๋ค. ํ์ง๋ง ์ด๋ ๋ง๋ฒ์ด ์๋๋ฉฐ, ๊ฐ๋ฐ์๊ฐ ์ ์ ํ ์ต์ ํ ๊ธฐ๋ฒ์ ์ ์ฉํ ๋ ๊ฐ์ฅ ํจ๊ณผ์ ์ผ๋ก ์๋ํ๋ค.