Skip to main content
Практика завдань

Що таке useSyncExternalStore в React?

Що таке useSyncExternalStore?

useSyncExternalStore — це хук React 18+ для підписки на зовнішні сховища — джерела даних, які існують поза React (API браузера, сторонні бібліотеки стану, глобальні змінні). Він забезпечує послідовне читання під час паралельного рендерингу.


Чому це потрібно

При паралельному рендерингу React може "призупинити" та "відновити" рендеринг. Без useSyncExternalStore ви можете прочитати різні значення зовнішнього сховища під час одного рендерингу — помилка, відома як розрив.

Основний API

tsx
const value = useSyncExternalStore( subscribe, // Функція для підписки на зміни getSnapshot, // Функція для отримання поточного значення getServerSnapshot // Необов'язково: значення для SSR );

Приклад: Статус онлайн

tsx
function useOnlineStatus() { return useSyncExternalStore( // subscribe — викликається, коли змінюється сховище (callback) => { window.addEventListener("online", callback); window.addEventListener("offline", callback); return () => { window.removeEventListener("online", callback); window.removeEventListener("offline", callback); }; }, // getSnapshot — повертає поточне значення () => navigator.onLine, // getServerSnapshot — значення для SSR () => true ); } function StatusBar() { const isOnline = useOnlineStatus(); return <div>{isOnline ? "🟢 Онлайн" : "🔴 Офлайн"}</div>; }

Приклад: Ширина вікна

tsx
function useWindowWidth() { return useSyncExternalStore( (callback) => { window.addEventListener("resize", callback); return () => window.removeEventListener("resize", callback); }, () => window.innerWidth, () => 1024 // Значення за замовчуванням для сервера ); } function Layout() { const width = useWindowWidth(); return width > 768 ? <DesktopLayout /> : <MobileLayout />; }

Приклад: localStorage

tsx
function useLocalStorage<T>(key: string, initialValue: T) { const subscribe = (callback: () => void) => { window.addEventListener("storage", callback); return () => window.removeEventListener("storage", callback); }; const getSnapshot = () => { const item = localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; }; const getServerSnapshot = () => initialValue; return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); } // Використання function Settings() { const theme = useLocalStorage("theme", "light"); return <div>Поточна тема: {theme}</div>; }

Як бібліотеки стану це використовують

Бібліотеки, такі як Zustand і Redux, внутрішньо використовують useSyncExternalStore:

tsx
// Спрощена концепція реалізації Zustand function useStore<T>(store: Store<T>, selector: (state: T) => any) { return useSyncExternalStore( store.subscribe, () => selector(store.getState()), () => selector(store.getInitialState()) ); }

Коли використовувати

СценарійВикористовувати
Стан React (useState, useReducer)❌ Не потрібно
API браузера (онлайн, зміна розміру, медіа-запит)✅ useSyncExternalStore
Сторонні сховища (без прив'язок до React)✅ useSyncExternalStore
Створення бібліотеки управління станом✅ useSyncExternalStore
Читання з localStorage/sessionStorage✅ useSyncExternalStore

Важливо:

useSyncExternalStore запобігає розриву в паралельному React, забезпечуючи послідовне читання з зовнішніх джерел даних. Використовуйте його для API браузера, сторонніх сховищ і будь-якого нестандартного стану. Якщо ви використовуєте стан React (useState/useReducer), вам це не потрібно — React вже коректно обробляє їх.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань