eact';  
    
    
      
    
    
    function ChatIndicator() {  
    
    
      const isOnline = useSyncExternalStore(subscribe, getSnapshot);  
    
    
      // ...  
    
    
    }

To implement the ` getSnapshot ` function, read the current value from the
browser API:

    
    
    function getSnapshot() {  
    
    
      return navigator.onLine;  
    
    
    }

Next, you need to implement the ` subscribe ` function. For example, when `
navigator.onLine ` changes, the browser fires the [ ` online `
](https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event) and [
` offline ` ](https://developer.mozilla.org/en-
US/docs/Web/API/Window/offline_event) events on the ` window ` object. You
need to subscribe the ` callback ` argument to the corresponding events, and
then return a function that cleans up the subscriptions:

    
    
    function subscribe(callback) {  
    
    
      window.addEventListener('online', callback);  
    
    
      window.addEventListener('offline', callback);  
    
    
      return () => {  
    
    
        window.removeEventListener('online', callback);  
    
    
        window.removeEventListener('offline', callback);  
    
    
      };  
    
    
    }

Now React knows how to read the value from the external ` navigator.onLine `
API and how to subscribe to its changes. Disconnect your device from the
network and notice that the component re-renders in response:

App.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    import { useSyncExternalStore } from 'react';
    
    export default function ChatIndicator() {
      const isOnline = useSyncExternalStore(subscribe, getSnapshot);
      return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
    }
    
    function getSnapshot() {
      return navigator.onLine;
    }
    
    function subscribe(callback) {
      window.addEventListener('online', callback);
      window.addEventListener('offline', callback);
      return () => {
        window.removeEventListener('online', callback);
        window.removeEventListener('offline', callback);
      };
    }
    
    

Show more

* * *

###  Extracting the logic to a custom Hook

Usually you won’t write ` useSyncExternalStore ` directly in your components.
Instead, you’ll typically call it from your own custom Hook. This lets you use
the same external store from different components.

For example, this custom ` useOnlineStatus ` Hook tracks whether the network
is online:

    
    
    import { useSyncExternalStore } from 'react';  
    
    
      
    
    
    export function useOnlineStatus() {  
    
    
      const isOnline = useSyncExternalStore(subscribe, getSnapshot);  
    
    
      return isOnline;  
    
    
    }  
    
    
      
    
    
    function getSnapshot() {  
    
    
      // ...  
    
    
    }  
    
    
      
    
    
    function subscribe(callback) {  
    
    
      // ...  
    
    
    }

Now different components can call ` useOnlineStatus ` without repeating the
underlying implementation:

App.js  useOnlineStatus.js

App.js

Reset  [ Fork
](https://codesandbox.io/api/v1/sandboxes/define?undefined&environment=create-
react-app "Open in CodeSandbox")

    
    
    import { useOnlineStatus } from './useOnlineStatus.js';
    
    function StatusBar() {
      const isOnline = useOnlineStatus();
      return <h1>{isOnline ? '✅ Online' : '❌ Disconnected'}</h1>;
    }
    
    function SaveButton() {
      const isOnline = useOnlineStatus();
    
      function handleSaveClick() {
        console.log('✅ Progress saved');
      }
    
      return (
        <button disabled={!isOnline} onClick={handleSaveClick}>
          {isOnline ? 'Save progress' : 'Reconnecting...'}
        </button>
      );
    }
    
    export default function App() {
      return (
        <>
          <SaveButton />
          <StatusBar />