useSyncExternalStore Hook in React

The useSyncExternalStore hook in React is designed to facilitate synchronization between React components and external data stores. This is particularly useful for managing state that exists outside the React component tree, such as data from APIs, local storage, or other global state management solutions. Below is a complete example demonstrating how to implement this hook in a real-world scenario.

Example: A Simple Todo List Application

This example will create a simple Todo List application that uses useSyncExternalStore to manage the state of todos stored in a simple external store.

Step 1: Setting Up the External Store

First, we need to create an external store that will manage our todo items. This store will provide methods to subscribe to changes and retrieve the current state.

// externalStore.js
let todos = [];
const listeners = new Set();

const subscribe = (listener) => {
  listeners.add(listener);
  return () => listeners.delete(listener);
};

const getSnapshot = () => todos;

const addTodo = (todo) => {
  todos.push(todo);
  listeners.forEach((listener) => listener());
};

export default {
  subscribe,
  getSnapshot,
  addTodo,
};

Step 2: Creating the Todo Component

Next, we will create a React component that uses useSyncExternalStore to subscribe to the external store and render the list of todos.

// TodoList.js
import React from "react";
import { useSyncExternalStore } from "react";
import externalStore from "./externalStore";

const TodoList = () => {
  const todos = useSyncExternalStore(
    externalStore.subscribe,
    externalStore.getSnapshot,
  );

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

export default TodoList;

Step 3: Creating the Input Component to Add Todos

Now, we will create an input component that allows users to add new todos to the list.

// TodoInput.js
import React, { useState } from "react";
import externalStore from "./externalStore";

const TodoInput = () => {
  const [inputValue, setInputValue] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    if (inputValue) {
      externalStore.addTodo(inputValue);
      setInputValue("");
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={inputValue}
        onChange={(e) => setInputValue(e.target.value)}
        placeholder="Add a new todo"
      />
      <button type="submit">Add Todo</button>
    </form>
  );
};

export default TodoInput;

Step 4: Putting It All Together

Finally, we will create the main application component that combines the TodoList and TodoInput components.

// App.js
import React from "react";
import TodoList from "./TodoList";
import TodoInput from "./TodoInput";

const App = () => {
  return (
    <div>
      <h1>Todo List</h1>
      <TodoInput />
      <TodoList />
    </div>
  );
};

export default App;

Conclusion

This example demonstrates how useSyncExternalStore can be used effectively to manage state in a React application, ensuring that components stay in sync with external data sources.

Latest blog posts

Explore the world of programming and cybersecurity through our curated collection of blog posts. From cutting-edge coding trends to the latest cyber threats and defense strategies, we've got you covered.