[React] virtual DOM, React Diffing

๋…ธํ˜ธ์ค€ยท2023๋…„ 3์›” 23์ผ
0

๐Ÿงฉ Virtual DOM

  • ๋ฆฌ์—‘ํŠธ์—๋Š” ๋ฒ„์ธ„์–ผ๋”์ด๋ผ๋Š” ๊ฐ€์ƒ์˜ dom๊ฐ์ฒด๊ฐ€ ์žˆ์Œ
  • ์‹ค์ œ dom์„ ์กฐ์ž‘ํ•˜๋Š” ๋Œ€์‹  ๋ฒ„์ธ„์–ผ๋”์— ์ ‘๊ทผํ•ด์„œ ์ ์šฉํ•จ
  • Real DOM : ๋ธŒ๋ผ์šฐ์ €๊ฐ€ html๋ฌธ์„œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํŠธ๋ฆฌ๊ตฌ์กฐํ™”ํ•œ ๊ฐ์ฒด๋ชจ๋ธ
  • querySelector, addEventListener ๊ฐ™์€ dom api๋กœ ๋ฌธ์„œ์š”์†Œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
  • Virtual DOM: DOM์—์„œ ๋ฐ”๋€ ๋ถ€๋ถ„๋งŒ ๋น„๊ตํ•ด์„œ ๊ทธ๋ถ€๋ถ„๋งŒ ๋ Œ๋”๋งํ•˜๋Š” ๊ธฐ์ˆ 

๐Ÿงฉ React Diffing Algorithm

  • ๋ฆฌ์•กํŠธ ์ž…์žฅ์—์„œ๋Š” ๋ณ€๊ฒฝ๋œ ๊ฐ€์ƒ DOM ํŠธ๋ฆฌ์— ๋ถ€ํ•ฉํ•˜๋„๋ก ๊ธฐ์กด์˜ UI๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ ํœด๋ฆฌ์Šคํ‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜(์‹œ๊ฐ„๋ณต์žกํ‘œ O(n))
  • BFS์˜ ์ผ์ข…, ๋™์ผ์„ ์ƒ์˜ ๋…ธ๋“œ๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ๋ฐ‘์œผ๋กœ ํŒŒ์•…ํ•ด๋‚˜๊ฐ€๋Š” ๋ฐฉ์‹

๐Ÿงฉ React Hook

  • Hook : ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์†Œ๋“œ, ๋Œ€ํ‘œ์ ์œผ๋กœ useState()๊ฐ€ ์žˆ์Œ.
  • Hook ์‚ฌ์šฉ๊ทœ์น™
    • ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜์˜ ์ตœ์ƒ์œ„์—์„œ๋งŒ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค : ๋ฐ˜๋ณต๋ฌธ ์กฐ๊ฑด๋ฌธ ๋“ฑ์—์„œ ์‹คํ–‰ํ•˜๋ฉด ์ž˜์ž‘๋™์•ˆํ•จ
    • ์˜ค์ง ๋ฆฌ์•กํŠธ ํ•จ์ˆ˜ ๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•œ๋‹ค : jsํ•จ์ˆ˜๋‚ด์—์„œ ๋ฆฌ์•กํŠธ hook ์•ˆ๋Œ์•„๊ฐ

๐Ÿšฉ useMemo

  • ํŠน์ • ๊ฐ’์„ ์žฌ์‚ฌ์šฉํ•˜๊ณ ์ž ํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” Hook
function Calculator({value}){

	const result = calculate(value);

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

props๋กœ ๋„˜์–ด์˜จ value๋ฅผ calculateํ•จ์ˆ˜์— ๋„˜๊ฒจ์„œ result๊ตฌํ•˜๊ณ  ์ถœ๋ ฅํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ
์—ฌ๊ธฐ์„œ calculateํ•จ์ˆ˜๊ฐ€ ๋ณต์žกํ•œ์—ฐ์‚ฐ์„ ํ•œ๋‹ค๋ฉด ๋ Œ๋”๋ง์ด ๊ธธ์–ด์ง

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

function Calculator({value}){

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

	return <>
      <div>
					{result}
      </div>
  </>;
}
  • useMemo์— calculate๊ฐ์‹ธ์ฃผ๋ฉด value๊ฐ’์ด ๋™์ผํ•œ๊ฒฝ์šฐ์—๋Š” ์ด์ „ ๋ Œ๋”๋ง value๊ฐ’์„ ๊ทธ๋Œ€๋กœ ์”€
  • useMemo๋Š” ๊ฐ’์˜ ์žฌ์‚ฌ์šฉ useCallback์€ ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•œ hook

๐Ÿšฉ Custom Hooks

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ์Šค์Šค๋กœ ์ปค์Šคํ…€ํ•œ ํ›…

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

  • ์ด๋Ÿฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋‹ค๊ณ  ์น˜์ž

//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์ปดํฌ๋„ŒํŠธ ๋‘˜๋‹ค ๊ฐ™์€๋กœ์ง์„ ์“ฐ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
  • ๊ทธ ๋กœ์ง์„ ์ปค์Šคํ…€ํ›… useFriendStatus๋กœ ๋งŒ๋“ค์–ด๋ณด์ž
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;
}
  • ๊ทœ์น™
    • ์ด๋ฆ„์•ž์— use๋ถ™์—ฌ์•ผํ•จ
    • ํ”„๋กœ์ ํŠธ ๋‚ด์˜ hooks๋””๋ ‰ํ† ๋ฆฌ์— custom hook์„ ์œ„์น˜์‹œ์ผœ์•ผํ•จ
    • ๋ฆฌํ„ดํ•˜๋Š” ๊ฐ’์€ ์กฐ๊ฑด๋ถ€์—ฌ์„œ๋Š” ์•ˆ๋จ.
  • ์œ„์˜ ์ปค์Šคํ…€ํ›…์„ ์ ์šฉํ•ด๋ณด์ž

๐Ÿงฉ React 18 ๊ธฐ๋Šฅ

  • ๋ฆฌ์•กํŠธ 18์€ ๋”์ด์ƒ ReactDOM.render์„ ์ง€์›ํ•˜์ง€ ์•Š์Œ

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