๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐ŸŽˆ Chapter 7: ๋ฆฌ์•กํŠธ ๋™์‹œ์„ฑ

๋™๊ธฐ์‹ ๋ Œ๋”๋ง์˜ ๋ฌธ์ œโ€‹

๊ฐ„๋‹จํžˆ ๋งํ•ด ๋™๊ธฐ์‹ ๋ Œ๋”๋ง์˜ ๋ฌธ์ œ๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€๋กœ๋ง‰์•„์„œ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ์ €ํ•œ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๊ฒƒ ํ•˜๋‚˜๋Š” ์—ฌ๋Ÿฌ ์—…๋ฐ์ดํŠธ๋ฅผ ์ผ๊ด„ ์ฒ˜๋ฆฌํ•ด์„œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์ž‘์—…์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๋ฆฌ์•กํŠธ๋Š” ๋™์‹œ์„ฑ ๋ Œ๋”๋ง(concurrent rendering)์„ ์‚ฌ์šฉํ•ด ์—…๋ฐ์ดํŠธ ์ž‘์—…์˜ ์ค‘์š”๋„์™€ ๊ธด๊ธ‰๋„์— ๋”ฐ๋ผ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•˜๊ณ , ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋œ ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ ๋•Œ๋ฌธ์— ๊ฐ€๋กœ๋ง‰์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฆฌ์•กํŠธ๋Š” ๋งŽ์€ ์ž‘์—…๋Ÿ‰์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  UI์˜ ์‘๋‹ต์„ฑ์„ ์œ ์ง€ํ•˜๊ณ , ๋” ๋‚˜์€ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒŒ์ด๋ฒ„ ๋‹ค์‹œ ๋ณด๊ธฐโ€‹

ํŒŒ์ด๋ฒ„ ์žฌ์กฐ์ •์ž๋Š” ๋ Œ๋”๋ง ํ”„๋กœ์„ธ์Šค๋ฅผ ํŒŒ์ด๋ฒ„๋ผ๊ณ  ํ•˜๋Š” ๋” ์ž‘๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ์ž‘์—… ๋‹จ์œ„๋กœ ๋ถ„ํ• ํ•ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฆฌ์•กํŠธ๋Š” ํŒŒ์ด๋ฒ„๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ Œ๋”๋ง ์ž‘์—…์„ ์ผ์‹œ์ ์œผ๋กœ ์ค‘์ง€ํ•˜๊ฑฐ๋‚˜ ์žฌ๊ฐœํ•˜๊ฑฐ๋‚˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์„ค์ •ํ•ด ์ค‘์š”๋„์— ๋”ฐ๋ผ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์—ฐํ•˜๊ฑฐ๋‚˜ ์˜ˆ์•ฝํ•ฉ๋‹ˆ๋‹ค. ๋•๋ถ„์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‘๋‹ต์„ฑ์ด ํ–ฅ์ƒ๋˜๊ณ  ๋œ ์ค‘์š”ํ•œ ์ž‘์—…์ด ๋” ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ€๋กœ๋ง‰๋Š” ์ผ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ ์˜ˆ์•ฝ๊ณผ ์ง€์—ฐโ€‹

์„œ๋ฒ„์—์„œ ์ƒˆ ๋ฉ”์‹œ์ง€๊ฐ€ ๋„์ฐฉํ•ด ์ด๋ฅผ ๋ Œ๋”๋งํ•ด์•ผ ํ•  ๋•Œ, ๋ฆฌ์•กํŠธ๋Š” ๋ Œ๋” ๋ ˆ์ธ์„ ํ†ตํ•ด ๋ Œ๋”๋งํ•˜๋Š”๋ฐ ์ด ๋ ˆ์ธ์€ ๋™๊ธฐ์‹์œผ๋กœ DOM์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด ๋‹ค๋ฅธ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ€๋กœ๋ง‰๊ฒŒ ๋˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ์ง€์—ฐ์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก์„ ๋ Œ๋”๋งํ•˜๋Š” ์ž‘์—…์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‚ฎ์ถ”๋ ค๋ฉด, ๊ด€๋ จ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด useTransition ํ›…์ด startTransition ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

const ChatApp = () => {
const [messages, setMessages] = useState([]);
const [isPending, startTransition] = useTransition();

useEffect(() => {
const socket = new WebSocket("wss://your-websocket-server.com");
socket.onmessage = (event) => {
startTransition(() => {
setMessages((prevMessages) => [...prevMessages, event.data]);
});
};

return () => {
socket.close();
};
}, []);

const sendMessage = (message) => {
// ๋ฉ”์‹œ์ง€๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†ก
}

return (
<div>
<MessageList messages={messages} />
<MessageInput onSubmit={sendMessage} />
</div>
);
};

์ด๋ฅผ ํ†ตํ•ด ๋ฆฌ์•กํŠธ๋Š” ๋ฉ”์‹œ์ง€ ๋ชฉ๋ก ์—…๋ฐ์ดํŠธ๋ฅผ ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„๋กœ ์˜ˆ์•ฝํ•ด์„œ UI๋ฅผ ๊ฐ€๋กœ๋ง‰์ง€ ์•Š๊ณ  ๋ Œ๋”๋งํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋ฐฉํ•ด๋ฐ›์ง€ ์•Š๊ณ , ์ˆ˜์‹ ๋˜๋Š” ๋ฉ”์‹œ์ง€๋Š” ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ๋ณด๋‹ค ๋‚ฎ์€ ์šฐ์„ ์ˆœ์œ„๋กœ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ํฐ ์ง€์žฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋” ๊นŠ์ด ๋“ค์–ด๊ฐ€๊ธฐโ€‹

์Šค์ผ€์ค„๋Ÿฌโ€‹

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

๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ด๋ฒคํŠธ ๋ฃจํ”„์—์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ์ž‘์—… ์ข…๋ฅ˜์˜ ํ•˜๋‚˜๋กœ, ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ๋ฐ”๋กœ ์‹คํ–‰๋˜๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค. ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ ํ๋กœ ๊ด€๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

์Šค์ผ€์ค„๋Ÿฌ๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ํ•จ์ˆ˜๊ฐ€ ์†์‚ฐ ๋ ˆ์ธ์— ๋”ฐ๋ผ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ์˜ˆ์•ฝํ•˜๋Š” ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.

๋ Œ๋” ๋ ˆ์ธโ€‹

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

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

  • setState๊ฐ€ ํด๋ฆญ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์—์„œ ํ˜ธ์ถœ๋˜๋ฉด, ํ•ด๋‹น ์—…๋ฐ์ดํŠธ๋Š” Sync ๋ ˆ์ธ(์šฐ์„ ์ˆœ์œ„ ๊ฐ€์žฅ ๋†’์Œ)์— ๋ฐฐ์ข…๋˜๋ฉฐ, ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ๋กœ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.
  • setState๊ฐ€ startTransition์˜ ํŠธ๋žœ์ง€์…˜ ๋‚ด์—์„œ ํ˜ธ์ถœ๋˜๋ฉด ํŠธ๋žœ์ง€์…˜ ๋ ˆ์ธ(์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์Œ)์— ๋ฐฐ์น˜๋˜๊ณ  ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ๋กœ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.

๊ฐ ๋ ˆ์ธ์€ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ์šฐ์„ ์ˆœ์œ„์— ๋Œ€์‘ํ•˜๋ฉฐ, ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ๋ ˆ์ธ์€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์€ ๋ ˆ์ธ๋ณด๋‹ค ๋จผ์ € ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

๋ Œ๋” ๋ ˆ์ธ ์ž‘๋™ ๋ฐฉ์‹โ€‹

์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๊ฑฐ๋‚˜ ์ƒˆ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋” ํŠธ๋ฆฌ์— ์ถ”๊ฐ€๋˜๋ฉด, ๋ฆฌ์•กํŠธ๋Š” ํ•ด๋‹น ์—…๋ฐ์ดํŠธ์˜ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์•ž์„œ ์„ค๋ช…ํ•œ ๋ ˆ์ธ์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์šฐ์„ ์ˆœ์œ„์˜ ์—…๋ฐ์ดํŠธ ์ข…๋ฅ˜(์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ, ๋ฐ์ดํ„ฐ ํŒจ์น˜, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—… ๋“ฑ)์™€ ์ปดํฌ๋„ŒํŠธ ๊ฐ€์‹œ์„ฑ ๊ฐ™์€ ์š”์ธ์— ๋”ฐ๋ผ ์ •ํ•ด์ง‘๋‹ˆ๋‹ค.
์ดํ›„ ๋ฆฌ์•กํŠธ๋Š” ๋‹ค์Œ ๋ฐฉ์‹์œผ๋กœ ๋ Œ๋” ๋ ˆ์ธ์„ ์‚ฌ์šฉํ•ด ์—…๋ฐ์ดํŠธ๋ฅผ ์˜ˆ์•ฝํ•˜๊ณ  ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•ฉ๋‹ˆ๋‹ค.

  1. ์—…๋ฐ์ดํŠธ ์ˆ˜์ง‘
    • ๋งˆ์ง€๋ง‰ ๋ Œ๋”๋ง ์ดํ›„์— ์˜ˆ์•ฝ๋œ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜์ง‘ํ•ด์„œ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ๊ฐ ๋ ˆ์ธ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ ˆ์ธ ์ฒ˜๋ฆฌ
    • ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๊ฐ€์žฅ ๋†’์€ ๋ ˆ์ธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๊ฐ ๋ ˆ์ธ์— ์žˆ๋Š” ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ ˆ์ธ์˜ ์—…๋ฐ์ดํŠธ๋Š” ํ•œ๊บผ๋ฒˆ์— ์ผ๊ด„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  3. ์ปค๋ฐ‹ ๋‹จ๊ณ„
    • ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ ํ›„, ์ปค๋ฐ‹ ๋‹จ๊ณ„๋กœ ์ง„์ž…ํ•ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ DOM์— ์ ์šฉํ•˜๊ณ , ํšจ๊ณผ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ๊ธฐํƒ€ ๋งˆ๋ฌด๋ฆฌ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ฐ˜๋ณต
    • ๋ Œ๋”๋ง์„ ํ•  ๋•Œ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•ญ์ƒ ์šฐ์„ ์ˆœ์œ„๋Œ€๋กœ ์ฒ˜๋ฆฌ๋˜๋„๋ก ๋ณด์žฅํ•˜๊ณ , ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์€ ์—…๋ฐ์ดํŠธ์— ์˜ํ•ด ๊ฐ€๋กœ๋ง‰์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋ฆฌ์•กํŠธ๋Š” ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์˜ฌ๋ฐ”๋ฅธ ๋ ˆ์ธ์— ์—…๋ฐ์ดํŠธ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ์ˆ˜๋™ ๊ฐœ์ž… ์—†์ด๋„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํšจ์œจ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๋ฆฌ์•กํŠธ๋Š” ๋‹ค์Œ ๋‹จ๊ป˜๋ฅผ ์ˆ˜ํ–‰ํ•ด ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  ์ ์ ˆํ•œ ๋ ˆ์ธ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.

  1. ์—…๋ฐ์ดํŠธ ์ฝ˜ํ…์ŠคํŠธ ํ™•์ธ
  • ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ ์ฝ˜ํ…์ŠคํŠธ๋ฅผ ํ‰๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ˜ํ…์ŠคํŠธ๋Š” ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ, ์ƒํƒœ ํ˜น์€ ํ”„๋กญ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ๋‚ด๋ถ€ ์—…๋ฐ์ดํŠธ, ์„œ๋ฒ„ ์‘๋‹ต์— ์˜ํ•œ ์—…๋ฐ์ดํŠธ์ผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ŠคํŠธ๋Š” ์—…๋ฐ์ดํŠธ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
  1. ์ฝ˜ํ…์ŠคํŠธ์— ๋”ฐ๋ผ ์šฐ์„ ์ˆœ์œ„ ์ถ”์ •
  • ์—…๋ฐ์ดํŠธ ์šฐ์„ ์ˆœ์œ„๋Š” ์ฝ˜ํ…์ŠคํŠธ์— ๋”ฐ๋ผ ์ถ”์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ปจ๋Œ€ ์—…๋ฐ์ดํŠธ๊ฐ€ ์‚ฌ์šฉใ…‡์ž ์ž…๋ ฅ์˜ ๊ฒฐ๊ณผ๋ผ๋ฉด ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์„ ๊ฒƒ์ด๋ฉฐ, ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ฐœ์ƒ์‹œํ‚จ ์—…๋ฐ์ดํŠธ๋Š” ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋‚ฎ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  1. ์šฐ์„ ์ˆœ์œ„ ์žฌ์ •์˜๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ
  • ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๊ฐœ๋ฐœ์ž๋Š” ๋ฆฌ์•กํŠธ์˜ useTransition ๋˜๋Š” useDeferredValue ํ›…์„ ์‚ฌ์šฉํ•ด ์—…๋ฐ์ดํŠธ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์žฌ์ •์˜๋œ ๊ฒฝ์šฐ์—๋Š” ์ถ”์ •ํ•œ ์šฐ์„ ์ˆœ์œ„ ๋Œ€์‹  ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •๋œ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  1. ์˜ฌ๋ฐ”๋ฅธ ๋ ˆ์ธ์— ์—…๋ฐ์ดํŠธ ํ• ๋‹น
  • ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๊ฒฐ์ •๋œ ํ›„์—๋Š” ํ•ด๋‹น ๋ ˆ์ธ์— ์—…๋ฐ์ดํŠธ๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์„ ์•ž์„œ ์‚ดํŽด๋ณธ ๋น„ํŠธ๋งˆ์Šคํฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฃจ์–ด์ง€๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฆฌ์•กํŠธ๋Š” ์—ฌ๋Ÿฌ ๋ ˆ์ธ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ทธ๋ฃนํ™”๋˜๊ณ  ์ฒ˜๋ฆฌ๋˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

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

๋ Œ์ธ ์ฒ˜๋ฆฌโ€‹

๊ฐ ๋ ˆ์ธ์— ์—…๋ฐ์ดํŠธ๊ฐ€ ํ• ๋‹น๋˜๋ฉด ๋ฆฌ์•กํŠธ๋Š” ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

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

์ปค๋ฐ‹ ๋‹จ๊ณ„โ€‹

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

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

ํšจ๊ณผ์˜ ํ”Œ๋Ÿฌ์‹ฑ ๋˜๋Š” ๋‚ด๋ณด๋‚ด๊ธฐ๋„ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ๋™๊ธฐ์‹ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ๋ฆฌ์•กํŠธ๋Š” ์—…๋ฐ์ดํŠธ ์ „ํ›„์— ๋Œ€๊ธฐ ์ค‘์ธ ํšจ๊ณผ๋ฅผ ํ•œ๊บผ๋ฒˆ์— ์‹คํ–‰ํ•˜๊ณ  ์ฒ˜๋ฆฌํ•ด์„œ ๋™๊ธฐ์‹ ์—…๋ฐ์ดํŠธ ์ƒํƒœ ๊ฐ„์— ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

useTransitionโ€‹

useTransition์€ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด UI๊ฐ€ ์‘๋‹ตํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋ฆฌ์•กํŠธ ํ›…์ž…๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ ์ด๋™ํ•˜๋Š” ๋“ฑ ์‹œ๊ฐ์ ์œผ๋กœ ํ˜ผ๋ž€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ์—…๋ฐ์ดํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

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

๊ฐ„๋‹จํ•œ ์˜ˆ์‹œโ€‹

import React, { useState, useTransition } from 'react';

function App() {
const [count, setCount] = useState(0);
const [isPending, startTransition] = useTransition();

const handleClick = () => {
doSomethingImportant();
startTransition(() => {
setCount(count + 1);
});
};

return (
<div>
<p>Count: {count}</p>
<button onClick={handleClick}>์ฆ๊ฐ€</button>
{isPending && <p>๋กœ๋”ฉ ์ค‘...</p>}
</div>
);
}

export default App;

setCount ์—…๋ฐ์ดํŠธ๋ฅผ startTransition ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์„œ ์ด ์—…๋ฐ์ดํŠธ๊ฐ€ ์ง€์—ฐ๋  ์ˆ˜ ์žˆ์Œ์„ ๋ฆฌ์•กํŠธ์— ์•Œ๋ฆฌ๊ณ , ์ด๋ฅผ ํ†ตํ•ด ๋†’์€ ์šฐ์„ ์ˆœ์œ„์˜ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋™์‹œ์— ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ UI๊ฐ€ ์‘๋‹ตํ•˜์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

useDeferredValueโ€‹

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

์ดˆ๊ธฐ ๋ Œ๋”๋ง ์ค‘์— ๋ฐ˜ํ™˜๋˜๋Š” ์ง€์—ฐ๋œ ๊ฐ’์€ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ๋œ ๊ฐ’๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ ์—…๋ฐ์ดํŠธ์—์„œ๋Š” useDeferredValue๊ฐ€ ์˜ค๋ž˜๋œ ๊ฐ’์„ ๋” ์˜ค๋ž˜ ์œ ์ง€ํ•˜๊ณ , ์ƒˆ ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธํ•  ์‹œ์ ์„ ์ œ์–ดํ•ด ๋ถ€๋“œ๋Ÿฌ์šด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ ์ง€ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ์ž‘์—…์ด ์—ฐ์‚ฐ ์ง‘์•ฝ์ ์ผ ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. useDeferredValue๋Š” ์ด์ „ ๊ฐ’๊ณผ ์ƒˆ ๊ฐ’ ์‚ฌ์ด์— ๋ Œ๋”๋ง์ด ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋„๋ก ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐ’์ด ๋ฐ”๋€Œ์–ด๋„ UI๊ฐ€ ๋งค๋ฒˆ ์ƒˆ๋กญ๊ฒŒ ๋ฆฌ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ์ƒˆ ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ๋  ์‹œ์ ์„ ์ œ์–ดํ•ด ํ•œ ๋ฒˆ์— ์ƒˆ ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜๊ธฐ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ stale-while-revalidate ์ „๋žต๊ณผ ์œ ์‚ฌํ•˜๋ฉฐ, ์ƒˆ ๊ฐ’์ด ๋„์ฐฉํ•˜๊ธฐ๊นŒ์ง€ ์ด์ „ ๊ฐ’์„ ์œ ์ง€ํ•จ์œผ๋กœ์จ UI์˜ ์‘๋‹ต์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.

useDeferredValue๋Š” ๋ฆฌ์•กํŠธ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์˜ ์ผ๋ถ€์ด๋ฉฐ ํŠน์ • ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์—ฐํ•˜๋Š” ๊ฒƒ์€ ๋ฌผ๋ก  ์ค‘๋‹จ๋„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

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

useDeferredValue์˜ ๋ชฉ์ โ€‹

useDeferredValue์˜ ์ฃผ์š” ๋ชฉ์ ์€ ๋œ ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ์˜ ๋ Œ๋”๋ง์„ ์ง€์—ฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž ์ƒํ˜ธ ์ž‘์šฉ๊ณผ ๊ฐ™์€ ๋” ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ, ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ ํ‘œ์‹œ์™€ ๊ฐ™์€ ๋œ ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ๋ณด๋‹ค ์šฐ์„  ์ฒ˜๋ฆฌํ•˜๋ ค๊ณ  ํ•  ๋•Œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

import React, { memo, useState, useDeferredValue } from 'react';

function App() {
const [searchValue, setSearchValue] = useState("");
const deferredSearchValue = useDeferredValue(searchValue);

return (
<div>
<input
type="text"
value={searchValue}
onChange={(event) => setSearchValue(event.target.value)}
/>
<SearchResults searchValue={deferredSearchValue} />
</div>
);
}

const SearchResults = memo(({ searchValue }) => {
// ๊ฒ€์ƒ‰๊ณผ ๊ฒฐ๊ณผ ๋ Œ๋”๋ง ์ˆ˜ํ–‰
})

useDeferredValue๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์˜ ๋ Œ๋”๋ง์„ ์ง€์—ฐํ•จ์œผ๋กœ์จ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

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

useDeferredValue ์‚ฌ์šฉ ์‹œ๊ธฐโ€‹

useDeferredValue ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•  ๋งŒํ•œ ์ผ๋ฐ˜์ ์ธ ์‚ฌ๋ก€๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

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

useDeferredValue๊ฐ€ ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐโ€‹

useDeferredValue๊ฐ€ ํŠน์ • ์ƒํ™ฉ์—์„œ๋Š” ์œ ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋ฅผ ์‚ฌ์šฉํ•ด ์–ป๋Š” ์žฅ์ ๊ณผ ๊ฐ์ˆ˜ํ•ด์•ผํ•  ๋‹จ์ ์„ ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—…๋ฐ์ดํŠธ๋ฅผ ์ง€์—ฐํ•˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œ๋˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ตœ์‹  ๋ฐ์ดํ„ฐ์™€๋Š” ๋‹ค๋ฅธ, ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ์ผ ์ˆ˜ ์žˆ๋ธŒ๋‹ˆ๋‹ค. ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋ผ๋ฉด ์ด๋Ÿฌํ•œ ์ง€์—ฐ์ด ํ—ˆ์šฉ๋˜๊ฒ ์ง€๋งŒ, ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์—ฐ๋œ ๋ฐ์ดํ„ธ๋ฅด ๋ณด๊ฒŒ ๋  ๋–„ ๋ฐœ์ƒํ•  ์˜ํ–ฅ์— ๋Œ€ํ•ด์„œ๋Š” ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

useDeferredValue์˜ ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ๋•Œ ์ž๋ฌธํ•  ๋งˆ๋•…ํ•œ ์งˆ๋ฌธ์€ '์ด ์—…๋ฐ์ดํŠธ๊ฐ€ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ์˜ํ•œ ๊ฒƒ์ธ๊ฐ€?'์ž…๋‹ˆ๋‹ค.

๋™์‹œ์„ฑ ๋ Œ๋”๋ง ๊ด€๋ จ ๋ฌธ์ œโ€‹

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

๋ฒ„๊ทธ์˜ ์ผ์ข…์ธ ํ‹ฐ์–ด๋ง(tearing)์ด๋ผ๋Š” ํ˜„์ƒ์€ ์—…๋ฐ์ดํŠธ ์ˆœ์„œ๊ฐ€ ์–ด๊ธ‹๋‚˜๋ฉด์„œ UI๊ฐ€ ์ผ๊ด€์„ฑ์„ ์žƒ๊ฒŒ ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. ์ด ํ˜„์ƒ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ Œ๋”๋ง๋˜๋Š” ๋™์•ˆ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ผ๊ด€๋˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋กœ ๋ Œ๋”๋ง๋˜๋ฉด์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ‹ฐ์–ด๋งโ€‹

ํ‹ฐ์–ด๋ง์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ฒ„๊ทธ์ž…๋‹ˆ๋‹ค.

๋™๊ธฐ์‹ ์„ธ๊ณ„์—์„œ๋Š” ๋ฆฌ์•กํŠธ๊ฐ€ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ๋”ฐ๋ผ ์œ„์—์„œ ์•„๋ž˜๋กœ ์ด๋™ํ•˜๋ฉฐ ํ•œ ์ปดํฌ๋„ŒํŠธ์”ฉ ์ฐจ๋ก€๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ Œ๋”๋ง ๊ณผ์ •์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๊ฐ€ ํ•ญ์ƒ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์‹  ์ƒํƒœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ Œ๋”๋ง๋˜๊ธฐ์— ๋ Œ๋”๋ง์ด ์ง„ํ–‰๋˜๋Š” ๋™์•ˆ UI๊ฐ€ ์ผ๊ด€์„ฑ์„ ์žƒ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

<UserDetails id={user.id} />

๋ Œ๋”๋งํ•˜๋Š” ๋„์ค‘ ์ „์—ญ ์ €์žฅ์†Œ์—์„œ ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ๊ฐ‘์ž๊ธฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ๋†€๋ž„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ‹ฐ์–ด๋ง์ด ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค.

ํ‹ฐ์–ด๋ง ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ์•กํŠธ๋Š” useSyncExternalStore๋ผ๋Š” ํ›…์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

useSyncExternalStoreโ€‹

useSyncExternalStore๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‚ด๋ถ€ ์ƒํƒœ์™€ ์™ธ๋ถ€ ์ƒํƒœ๋ฅผ ๋™๊ธฐํ™”ํ•˜๋Š” ๋ฆฌ์•กํŠธ ํ›…์ž…๋‹ˆ๋‹ค. ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ํ‹ฐ์–ด๋ง์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ๋น„์šฉ ๊ณ„์‚ฐ ์ž‘์—…์„ ํ•  ๋–„ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. useSyncExternalStore๋ผ๋Š” ์ด๋ฆ„์˜ 'sync'์—๋Š” ๋‘ ๊ฐ€์ง€ ์˜๋ฏธ๊ฐ€ ๋‹ด๊ฒผ์Šต๋‹ˆ๋‹ค. ๋™๊ธฐํ™”(synchronize)์™€ ๋™๊ธฐ์ (synchronous)์ด๋ผ๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด ์™ธ๋ถ€ ์ €์žฅ์†Œ์— ๋ณ€ํ™”ํ•ด ๋ฐœ์ƒํ•  ๋•Œ ๋™๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ•์ œํ•ด ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

useSyncExternalStore ํ›…์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const value = useSyncExternalStore(store.subscribe, store.getSnapshot);

store.subscribe

์œ ์ผํ•œ ์ธ์ˆ˜๋กœ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋Š” ์™ธ๋ถ€ ์ €์žฅ์†Œ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ตฌ๋…ํ•˜๊ณ  ์ €์žฅ์†Œ์— ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธธ ๋•Œ๋งˆ๋‹ค ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์•กํŠธ๋Š” ์ด ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ์ƒˆ ๊ฐ’์„ ์‚ฌ์šฉํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฆฌ๋ Œ๋”๋งํ•˜๋ผ๋Š” ์‹ ํ˜ธ๋กœ ๊ฐ„์ฃผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ •๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๋ฐ ๋ฐ˜ํ™˜๋œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์™ธ๋ถ€ ์ €์žฅ์†Œ์˜ ๊ตฌ๋…์„ ์ทจ์†Œํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ subscribe ํ•จ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const store = {
subscribe(rerender) {
const newData = getNewData().then(rerender);
return () => {
// ๊ตฌ๋… ํ•ด์ œ
};
},
};

subscribe ํ•จ์ˆ˜๋Š” ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” resize ๋˜๋Š” scroll ์ด๋ฒคํŠธ์™€ ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ € ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

const store = {
subscribe(rerenderImmediately) {
window.addEventListener("resize", rerenderImmediately);
return () => {
window.removeEventListener("resize", rerenderImmediately);
};
},
};

์ด์ œ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ ํฌ๊ธฐ๊ฐ€ ์กฐ์ •๋  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ƒˆ๋กœ ์—…๋ฐ์ดํŠธ๋œ ๊ฐ’์€ ์–ด๋–ป๊ฒŒ ์–ป์„๊นŒ์š”? ๋ฐ”๋กœ ์ด ๋Œ€๋ชฉ์—์„œ useSyncExternalStore์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

store.getSnapshot

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

const store = {
subscribe(immediatelyRerenderSynchronously) {
window.addEventListener("resize", immediatelyRerenderSynchronously);
return () => {
window.removeEventListener("resize", immediatelyRerenderSynchronously);
};
},
getSnapshot() {
return {
width: window.innerWidth,
height: window.innerHeight,
}
}
};

์—ฌ๊ธฐ์„œ { width, height } ๊ฐ์ฒด๋Š” ์ฐฝ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์Šค๋ƒ…์ˆ์ด๋ฉฐ, useSyncExternalStore๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ๋™์‹œ์  ๋ Œ๋”๋ง ์ƒํ™ฉ์—์„œ๋„ ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์œ ์ง€๋œ๋‹ค๋Š” ํ™•์ธ์„ ๊ฐ€์ง€๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ™•์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ทผ๊ฑฐ๊ฐ€ ๋ฌด์—‡์ผ๊นŒ์š”? immediatelyRerenderSynchronously ํ•จ์ˆ˜๊ฐ€ ๋™๊ธฐ์‹ ๋ฆฌ๋ Œ๋”๋ง์„ ๊ฐ•์ œํ•˜๊ณ  ๋ฆฌ์•กํŠธ๊ฐ€ ์ด ๋ Œ๋”๋ง์„ ์ง€์—ฐํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ฐ”๋กœ ํ‹ฐ์–ด๋ง ๋ฌธ์ œ ํ•ด๊ฒฐ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

useSyncExternalStore๊ฐ€ ์ฃผ์š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์€

  • ๋™์‹œ์  ๋ Œ๋”๋ง์—์„œ ์ผ๊ด€๋œ ์ƒํƒœ ๋ณด์žฅํ•˜๊ธฐ
  • ์ €์žฅ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋™๊ธฐ์ ์œผ๋กœ ๋ฆฌ๋ Œ๋”๋ง ๊ฐ•์ œ ์ ์šฉํ•˜๊ธฐ