React Hook.const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot?)
subscribe: 단일 콜백 인수를 받아서 스토어에 구독하는 함수. 스토어가 변경되면 제공된 콜백을 호출해야 한다. 그러면 컴포넌트가 다시 렌더링된다. subscribe는 구독을 정리하는(cleans up the subscription) 함수를 반환해야 한다.
getSnapshot: 컴포넌트에 필요한 스토어의 데이터 스냅샷을 반환하는 함수. 스토어가 변경되지 않은 동안 getSnapshot에 대한 반복적인 호출은 동일한 값을 반환해야 한다. 스토어가 변경되고 반환된 값이 다르면 React는 구성 요소를 다시 렌더링한다.
getServerSnapshot(optional): 스토어에 있는 데이터의 초기 스냅샷을 반환하는 함수. 서버 렌더링과 클라이언트에서 서버 렌더링된 콘텐츠의 하이드레이션 중에만 사용된다. 서버 스냅샷은 클라이언트와 서버 간에 동일해야 하며, 일반적으로 직렬화되어 서버에서 클라이언트로 전달된다. 이 인자를 생략하면 서버에서 구성 요소를 렌더링할 때 오류가 발생한다.
getSnapshot에서 반환된 스토어 스냅샷은 변경 불가능해야 한다. 기본 스토어에 변경 가능한 데이터가 변경된 경우 새 변경 불가능한 스냅샷을 반환한다. 그렇지 않은 경우 캐시된 마지막 스냅샷을 반환한다.
리렌더링 중에 다른 subscribe가 전달되면 React는 새로 전달된 구독 함수를 사용하여 스토어를 다시 subscribe합니다. 컴포넌트 외부에서 subscribe을 선언하면 이를 방지할 수 있다.
non-blocking Transition update 중에 스토어가 변형되면 React는 해당 업데이트를 blocking으로 수행한다. 구체적으로, 모든 전환 업데이트에 대해 React는 DOM에 변경 사항을 적용하기 직전에 getSnapshot을 두 번째로 호출한다. 원래 호출되었을 때와 다른 값을 반환하면 React는 업데이트를 처음부터 다시 시작하여 이번에는 blocking 업데이트로 적용하여 화면의 모든 구성 요소가 동일한 버전의 스토어를 반영하도록 한다.
useSyncExternalStore에서 반환된 스토어 값에 따라 렌더링을 일시 중단하는 것은 권장되지 않는다. 그 이유는 외부 스토어에 대한 변형은 non-blocking Transition update로 표시할 수 없기 때문에 가장 가까운 Suspense fallback(화면에 이미 렌더링된 콘텐츠를 로딩 스피너로 대체하는)을 트리거할 것이다.
const LazyProductDetailPage = lazy(() => import('./ProductDetailPage.js'));
function ShoppingApp() {
const selectedProductId = useSyncExternalStore(...);
// ❌ Calling `use` with a Promise dependent on `selectedProductId`
const data = use(fetchItem(selectedProductId))
// ❌ Conditionally rendering a lazy component based on `selectedProductId`
return selectedProductId != null ? <LazyProductDetailPage /> : <FeaturedProducts />;
}
React 컴포넌트는 props, state 및 context에서만 데이터를 읽는다. React 외부의 일부 저장소에서 일부 데이터를 읽어야 한다.(참고)useSyncExternalStore를 호출하여 외부 데이터 저장소에서 값을 읽는다.
React외부에서 상태를 유지하는 상태 관리 라이브러리.
변경 가능한 값과 이벤트를 노출하여 변경 사항을 구독하는Browers API.
import { useSyncExternalStore } from 'react';
import { todosStore } from './todoStore.js';
function TodosApp() {
const todos = useSyncExternalStore(todosStore.subscribe, todosStore.getSnapshot);
// ...
}
React는 이러한 함수를 사용하여 컴포넌트를 스토어에 구독하고 변경 사항이 있을 때 다시 렌더링한다.
useSyncExternalStore를 컴포넌트에 직접 작성하지 않는다. custom Hook에서 호출한다. 이렇게 하면 다른 컴포넌트에서 동일한 외부 저장소를 사용할 수 있다.import { useSyncExternalStore } from 'react';
export function useOnlineStatus() {
const isOnline = useSyncExternalStore(subscribe, getSnapshot);
return isOnline;
}
function getSnapshot() {
// ...
}
function subscribe(callback) {
// ...
}
getSnapshot 함수가 호출될 때마다 새 객체를 반환한다는 것을 의미.function getSnapshot() {
// 🔴 Do not return always different objects from getSnapshot
return {
todos: myStore.todos
};
}
getSnapshot 객체는 실제로 무언가가 변경된 경우에만 다른 객체를 반환해야 한다.
스토어에 변경 불가능한 데이터가 포함된 경우 해당 데이터를 직접 반환할 수 있다.
function getSnapshot() {
// ✅ You can return immutable data
return myStore.todos;
}
useState와 useReducer를 사용하여 내장된 React 상태를 사용하는 것이 좋다. useSyncExternalStore는 기존 비 non-React 코드와 통합해야 하는 경우에 주로 유용하다.
현기증 나요 다음 화 얼른 올려주세요!!