ClientOnly
- 아래와 같이 정의되어 있는 useInClient 라는 훅을 호출한다.
import { noop } from '@suspensive/utils'
import { useSyncExternalStore } from 'react'
const emptySubscribe = () => noop
const getSnapshot = () => true
const getServerSnapshot = () => false
export const useIsClient = () => useSyncExternalStore(emptySubscribe, getSnapshot, getServerSnapshot)
- 이는 useSyncExternalStore의 동작원리를 사용한건데, 이는 아래와 같이 세개의 인자를 갖는다.
- subscribe
- getSnapshot
- getServerSnapshot
- 따라서, 서버에서 실행 될 때, 리액트는
getServerSnapshot
을 호출하여 false
를 얻고, 클라이언트에서 실행될 때는 getSnapshot
을 호출하여 true
를 얻는다.
- 이 방식이 가능한 이유는 리액트의 하이드레이션 (hydration)과정 때문에다. 서버에서 초기 렌더링을할 때는
getServerSnapshot
이 사용되고, 클라이언트에서 hydration이 완료된 후에는 getSnapshot이 사용된다.
- 따라서, 이 훅을 사용하는 컴포넌트는 서버에서 렌더링 될 때와, 클라이언트에서 렌더링될 때 다른 값을 받게 되며 이를 통해 현재 환경이 클라이언트인지 서버인지 구분 가능함.
- noop 함수를 subscribe 로 넘기는 이유는?