๐Ÿ‘€ Suspensive v2์—์„œ์˜ ๋ณ€๊ฒฝ์„ ํ™•์ธํ•˜์„ธ์š”. ๋”๋ณด๊ธฐ โ†’
๋ฌธ์„œ๋ณด๊ธฐ@suspensive/react<Suspense/>

Suspense

@suspensive/react์˜ <Suspense/>๋Š” React์˜ Suspense๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

props.fallback

fallback์€ react์˜ Suspense์˜ fallback์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

import { Suspense } from '@suspensive/react'
 
const Example = () => (
  <Suspense fallback={<Loading />}>
    <Children />
  </Suspense>
)
๐Ÿ’ก

Default fallback

<Suspense/>๋Š” <DefaultPropsProvider/>์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๋”์šฑ ๊ฐ•๋ ฅํ•ด์ง‘๋‹ˆ๋‹ค. <DefaultPropsProvider/>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ <Suspense/>์˜ default fallback๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ <DefaultPropsProvider/> ํŽ˜์ด์ง€์— ์†Œ๊ฐœ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ํ”ผํ•˜๊ธฐ (clientOnly)

clientOnly prop์„ ์‚ฌ์šฉํ•˜๋ฉด <Suspense/>๋Š” ์„œ๋ฒ„์—์„œ๋Š” fallback์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. mount ํ›„(ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š”) children์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. mount๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ๋งŒ ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { Suspense } from '@suspensive/react'
 
const Example = () => (
  <Suspense clientOnly fallback={<Loading />}>
    <Children />
  </Suspense>
)

clientOnly prop์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ useIsClientํ›…์„ ์‚ฌ์šฉํ•˜๊ณ  useIsClient๋Š” useSyncExternalStore์˜ getSnapshot์™€ getServerSnapshot์„ ํ™œ์šฉํ•ด client์ž„์„ ๋ณด์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

const useIsClient = () =>
  useSyncExternalStore(emptySubscribe, getSnapshot, getServerSnapshot)
 
const emptySubscribe = () => noop
const getSnapshot = () => true
const getServerSnapshot = () => false

https://x.com/TkDodo/status/1741068994981826947?t=XmG17etMUL2m0JFim03vqw&s=19

SSR์„ ์ง€์›ํ•˜๋„๋ก ์ ์ง„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๊ธฐ (<Suspense clientOnly/> -> <Suspense/>)

React.Suspense๋ฅผ SSR๊ณผ CSR์—์„œ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด <Suspense clientOnly/>์—์„œ <Suspense/>๋กœ ์ ์ง„์ ์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.