๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“ Study/โ„๏ธ React

useSyncExternalStore?

๐Ÿ’ก ํ•™์Šต ๊ณต์œ  ์Šคํ„ฐ๋””์—์„œ ๋ฐœํ‘œ๋ฅผ ์œ„ํ•ด ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.
๐Ÿค ๋น ๋ฅธ ์ž‘์„ฑ์„ ์œ„ํ•ด ์Œ์Šด์ฒด๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
โ˜ ๏ธ ํ•™์Šต ์ค‘์— ์ž‘์„ฑํ•œ ๊ธ€์ด๋ฏ€๋กœ ๋‚ด์šฉ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!
๐Ÿฅฐ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ•˜์‹ ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

โœ”๏ธ useSyncExternalStore ์™œ ๋‚˜์˜ด?

1. React 18์˜ ํ˜์‹ , Concurrency

React ํŒ€์€ React 18์„ ๋ฐœํ‘œํ•˜๋ฉด์„œ, ์ด๋ฒˆ ๋ฆด๋ฆฌ์ฆˆ๋Š” ๋™์‹œ์„ฑ(Concurrency) ์˜ ๋„์ž…์œผ๋กœ ๋ Œ๋”๋ง ์—”์ง„ ๊ฐœ์„ (์ž๋™๋ฐฐ์นญ)๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ(transition, suspense)์— ์ง‘์ค‘ํ–ˆ๋‹ค๊ณ  ํ•จ.

 

๋™์‹œ์„ฑ์ด ๋จผ๋””?

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

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

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

 

์˜ˆ์‹œ : startTransition

React 18์—์„œ๋Š” ์—…๋ฐ์ดํŠธ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ๋ถ„ํ•˜์—ฌ ์ƒ๊ฐ ํ•จ.

  • ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ (urgent updates) : ์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๊ฐ™์€ ๋‹ค์ด๋ ‰ํŠธ ์ƒํ˜ธ์ž‘์šฉ์„ ๋ฐ˜์˜
  • ์ „ํ™˜ ์—…๋ฐ์ดํŠธ (transition updates) : UI์˜ ์ „ํ™˜

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

import { startTransition } from 'react';

// ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ : ์ž…๋ ฅํ•˜๊ณ  ์žˆ๋Š” ๊ฐ’
setInputValue(input);

// startTransition์œผ๋กœ ๋ž˜ํ•‘๋œ ์—…๋ฐ์ดํŠธ๋Š” ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๊ณ , ๋” ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์ค‘๋‹จ๋œ๋‹ค.
startTransition(() => {
  // ์ „ํ™˜ ์—…๋ฐ์ดํŠธ: ์ž…๋ ฅ๊ฐ’์— ๋”ฐ๋ฅธ ์ฟผ๋ฆฌ๊ฐ’
  setSearchQuery(input);
});

์œ„์™€ ๊ฐ™์ด startTransition ์œผ๋กœ ๋žฉํ•‘๋œ ์—…๋ฐ์ดํŠธ๋Š” ์ „ํ™˜ ์—…๋ฐ์ดํŠธ๋กœ ์ฒ˜๋ฆฌ๋˜์–ด ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์ค‘๋‹จ๋จ.

 

startTransition์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ธ”๋กœํ‚น ๋ Œ๋”๋ง ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์˜ˆ์‹œ

 

2. ํ˜์‹ ๊ณผ ํ•จ๊ป˜ ๋– ์˜ค๋ฅธ ๋ฌธ์ œ?!

React System ๋‚ด์—์„œ๋Š” ํ›Œ๋ฅญํ•จ. ํ•˜์ง€๋งŒ ์™ธ๋ถ€ ์Šคํ† ์–ด(external store) ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์˜์กดํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฒฝ์šฐ tearing ์ด๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์™ธ๋ถ€ ์Šคํ† ์–ด vs ๋‚ด๋ถ€ ์Šคํ† ์–ด

  • Internal store(states) : React ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ ๋˜๋Š” ์Šคํ† ์–ด, useState, useReducer, context, props ๋“ฑ
  • External store
    • React์—์„œ ์ œ๊ณตํ•˜๋Š” ์ƒํƒœ๊ด€๋ฆฌ api ์™ธ์˜ ์ž์ฒด์ ์œผ๋กœ ์ƒํƒœ ๊ด€๋ฆฌ ํˆด์„ ๋งŒ๋“ค์–ด ๋ฆฌ์•กํŠธ ํ›…๊ณผ ์—ฐ๋™์‹œํ‚จ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(mobx, redux, recoil, zustand ๋“ฑ)
    • Dom ๊ฐ์ฒด, Web API(Date) ๋“ฑ
    • ref ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ณ€์ˆ˜ ๊ฐ’

๋น„๋™์‹œ ๋ Œ๋”๋ง vs ๋™์‹œ ๋ Œ๋”๋ง - What is tearing?

  1. React ์˜ ๋ Œ๋”๋ง ์ž‘์—…์ด ์‹œ์ž‘๋จ. external store ์— ์ ‘๊ทผํ•ด์„œ ์ƒ‰์ƒ ๊ฐ’์„ ๊ฐ€์ ธ์™€์„œ ๋ Œ๋”๋งํ•จ.
  2. ๋ Œ๋”๋ง์„ ๊ณ„์† ์ง„ํ–‰ํ•จ ์—ฌ์ „ํžˆ external store ๋Š” ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง.
  3. ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŒŒ๋ž€์ƒ‰์œผ๋กœ ๋ Œ๋”๋ง ๋˜๊ณ  ๋ชจ๋‘ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์ž˜ ๋ณด์ž„.
  4. ๋ Œ๋”๋ง ํ›„์— external store ๋Š” ์—…๋ฐ์ดํŠธ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Œ. React ์—์„œ ๋ Œ๋”๋ง์ด ๋‹ค ๋๋‚œ ๋‹ค์Œ ๋‹ค๋ฅธ ์ž‘์—…์ด ์ผ์–ด๋‚˜๋„๋ก ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— React ๊ฐ€ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์„ ๋•Œ ์Šคํ† ์–ด๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜๋ฉด ๋‹ค์Œ์— React ๊ฐ€ ํŠธ๋ฆฌ๋ฅผ ๋ Œ๋”๋ง ํ•  ๋•Œ ์ฒซ๋ฒˆ์งธ ๊ณผ์ •๋ถ€ํ„ฐ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์„œ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง€๊ฒŒ ๋จ

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

๊ทธ๋ ‡๋‹ค๋ฉด ๋งŒ์•ฝ์— ๋‘๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์Šคํ† ์–ด๋ฅผ ํŒŒ๋ž€์ƒ‰์—์„œ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๋‹ค๋ฉด?

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

 

Tearing Example - reference 

 

์ด๋Ÿฌํ•œ Tearing ์„ ํ•ด๊ฒฐํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ์™ธ๋ถ€ ์ €์žฅ์†Œ์˜ ๊ฐ’์„ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋‚˜์˜จ ๊ฒƒ์ด ๋ฐ”๋กœ useSyncExternalStore ์ธ ๊ฒƒ!!!

 

โœ”๏ธ useSyncExternalStore ๊ฐ„๋‹จ ์‚ฌ์šฉ๋ฒ•

useSyncExternalStore ๋Š” Tearing ๋ฌธ์ œ ์—†์ด ์™ธ๋ถ€ ์ €์žฅ์†Œ๋ฅผ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋Š” React Hook.

2๊ฐœ์˜ ํ•„์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ 1๊ฐœ์˜ ์˜ต์…”๋„ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›๊ณ  getSnapshot ์˜ ๊ฒฐ๊ณผ๋ฌผ์ธ snapshot(์ƒํƒœ๊ฐ’) ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

  1. subscribe : ํ•˜๋‚˜์˜ callback ์ธ์ž(onStoreChange)๋ฅผ ๋ฐ›์•„์™€ ์Šคํ† ์–ด์— ๊ตฌ๋…ํ•˜๋Š” ํ•จ์ˆ˜. ์Šคํ† ์–ด๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ œ๊ณต๋œ ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœ. ์ด๋กœ ์ธํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋œ๋‹ค. ๊ตฌ๋…์„ ์ •๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜(clean up)๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.
  2. getSnapshot : ์ปดํฌ๋„ŒํŠธ์— ํ•„์š”ํ•œ ์ €์žฅ์†Œ์˜ ๋ฐ์ดํ„ฐ ์Šค๋ƒ…์ƒท์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜. ์ €์žฅ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋™์•ˆ getSnapshot ์— ๋Œ€ํ•œ ๋ฐ˜๋ณต ํ˜ธ์ถœ์€ ๋™์ผํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. ์ €์žฅ์†Œ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ณ  ๋ฐ˜ํ™˜๋œ ๊ฐ’์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ(Object.is) ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•œ๋‹ค.
  3. getServerSnapshot : ์ €์žฅ์†Œ์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ์ดˆ๊ธฐ ์Šค๋ƒ…์ƒท์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜. ์„œ๋ฒ„ ๋ Œ๋”๋ง ์‹œ ํด๋ผ์ด์–ธํŠธ์—์„œ ์„œ๋ฒ„ ๋ Œ๋”๋ง ์ฝ˜ํ…์ธ ์˜ hydration ์ž‘์—… ๋„์ค‘์— ์‚ฌ์šฉ๋จ. ์„œ๋ฒ„ ์Šค๋ƒ…์ƒท์€ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„์— ๋™์ผํ•ด์•ผ ํ•˜๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ์ง๋ ฌํ™”(serialized) ๋˜์–ด ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌ๋จ. ์ด ํ•จ์ˆ˜๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์œผ๋ฉด ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ์‹œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ. ⇒ SSR์„ ์œ„ํ•œ ๊ธฐ๋Šฅ

์˜ˆ์‹œ : TodoList Store

 

โœ”๏ธ ๊ทผ๋ฐ ๋‚˜๋Š” ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ํ™œ์šฉ ์•ˆํ•˜๋Š”๋ฐ?

๋˜ํ•œ ์•ž์œผ๋กœ์˜ React ๊ฐ€ ๋‚˜์•„๊ฐ€๋Š” ๋ฐฉํ–ฅ์˜ ํฐ ์ถ•์ด ๋™์‹œ์„ฑ ๋ Œ๋”๋ง์ธ ๋งŒํผ ์–ธ์ œ ์–ด๋””์„œ ์–ด๋–ป๊ฒŒ ๋™์‹œ์„ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ ํ•˜๊ฒŒ ๋ ์ง€ ๋ชจ๋ฅด๊ณ , ๊ทธ๋ ‡๊ธฐ์— ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์–ธ์ œ ๋ฌธ์ œ๊ฐ€ ๋ ์ง€ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†์Œ.

๋”ฐ๋ผ์„œ Jotai, Zustand ์˜ ๊ฐœ๋ฐœ์ž ์นดํ†  ๋‹ค์ด์‹œ๋Š” ์ฝ”๋“œ ๋‚ด์—์„œ ์™ธ๋ถ€ ์ €์žฅ์†Œ์™€ ๋‚ด๋ถ€ ์ €์žฅ์†Œ๋ฅผ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•˜์—ฌ ์™ธ๋ถ€ ์ €์žฅ์†Œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ์ฝ”๋“œ๋Š” useSyncExternalStore ๋ฅผ ์ ๊ทน ํ™œ์šฉํ•˜๋Š”๊ฑธ ๊ถŒ์žฅํ•จ.

(ํŠนํžˆ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ๋Š” ๋”๋”์šฑ ์‚ฌ์šฉ์ž๊ฐ€ ๋™์‹œ์„ฑ ์ง€์› ์—ฌ๋ถ€๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋งŒํผ ๊ฑฐ์˜ ํ•„์ˆ˜.)

 

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

๋˜ํ•œ ํ•ด๋‹น ํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด Context API ๋“ฑ์œผ๋กœ ๋ณต์žกํ•œ ์ƒํƒœ๊ฐ’์„ ํ†ต์ฑ„๋กœ ์ฐธ์กฐํ•ด์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ๋ฌธ์ œ๋„ ์Šค๋ƒ…์ƒท ํ•จ์ˆ˜๋กœ ํŠน์ • ๊ฐ’๋งŒ ์ฐธ์กฐํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜๋ฉด ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง๋„ ์ค„์ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Œ. → ํ˜„์žฌ cos-ui form ์— ์ ์šฉ ์‹œ๋„ ์ค‘

๊ทธ๋Ÿฌํ•œ ๋กœ์ง์„ ๋˜ ์ด์ „์—” useState์™€ useEffect ๋ฅผ ์จ์„œ ๋‹ค์†Œ ๋ณต์žกํ•˜๊ฒŒ ๊ตฌํ˜„์„ ํ•ด์•ผ ํ–ˆ๋Š”๋ฐ ์ด์   subscribe ํ•จ์ˆ˜๋งŒ ์ž˜ ๊ตฌํ˜„ํ•ด๋†“์œผ๋ฉด useSyncExternalStore ํ•˜๋‚˜๋กœ ํ•ด๊ฒฐ์ด ๊ฐ€๋Šฅํ•จ. ๊ทธ๋Ÿผ ์ฝ”๋“œ๊ฐ€ ์ข€ ๋” ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์ง€๋Š”๊ฒŒ ์•„๋‹๊นŒ?

 

โœ”๏ธ ๊ทธ๋ž˜์„œ ์ฐพ์•„๋ณธ useSyncExternalStore ๋ฅผ ํ™œ์šฉํ•œ ๋˜๋‹ค๋ฅธ ์˜ˆ์‹œ

 

โœ”๏ธ ์ฐธ๊ณ ํ•œ ์ž๋ฃŒ

 โญ๏ธ React Docs : useSyncExternalStore : React Docs useSyncExternalStore ๊ณต์‹๋ฌธ์„œ

 โญ๏ธ React Conf 2021 : React 18 for External Store Libraries : Zustand ๊ฐœ๋ฐœ์ž ์นดํ†  ๋‹ค์ด์‹œ ๋ฐœํ‘œ ์˜์ƒ โญ๏ธ

Zustand ๋™์ž‘ ์›๋ฆฌ์™€ ExternalStore

https://velog.io/@jay/useSyncExternalStore

React 18์˜ useSyncExternalStore, Tearing ํ˜„์ƒ์€ ๋ฌด์—‡์ธ๊ฐ€?

์‰ฝ๊ฒŒ ๋– ๋จน์—ฌ์ฃผ๋Š” React 18 ์—…๋ฐ์ดํŠธ