LogRocket Blog

Exploring useSyncExternalStore, a lesser-known React Hook

thumbnail

Introduction to useSyncExternalStore

useSyncExternalStore is a lesser-known React Hook that allows you to subscribe to an external data store. It takes in three parameters: a subscribe callback function, a currentData function that returns the current snapshot of external store data, and an optional initialData parameter for the initial store data snapshot.

Use Cases for useSyncExternalStore

  • Caching data from external APIs
  • Managing WebSocket connections
  • Syncing browser storage like IndexedDB and localStorage

useSyncExternalStore vs. useState

While you can achieve similar functionality with useState, it lacks the ability to provide current snapshots for each state update and is more error-prone. useSyncExternalStore is more reliable for managing external data.

Addressing the Rendering Sequence Issue

useSyncExternalStore helps avoid issues with the sequence of rendering in React, especially when dealing with externally located data that doesn't depend on existing React APIs. It provides a global state that can be subscribed to from any component, preventing performance slowdowns.

Implementation Example

Here's a simple example of using useSyncExternalStore to manage a global state and subscribe to it in a React component:

// ExternalDataStore.js
import { useSyncExternalStore } from 'react';

const ExternalDataStore = () => {
  const [todos, setTodos] = useState([]);

  const subscribe = (callback) => {
    // Subscribe to external data source
    // Update todos state
  };

  const currentData = () => todos;

  return useSyncExternalStore(subscribe, currentData);
};

// TodoList.js
import React from 'react';
import ExternalDataStore from './ExternalDataStore';

const TodoList = () => {
  const todos = ExternalDataStore();

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

In this example, ExternalDataStore manages the global state of to-do items, and TodoList subscribes to this data and renders it on the UI.