Blog>
Snippets

Persisting Form State to an External Store

Provide an example of using useSyncExternalStore to persist form state to an external store and retrieve it back when the component mounts.
// External store setup
const formStateStore = (() => {
  let state = { name: '', email: '' };
  const listeners = new Set();

  return {
    subscribe(listener) {
      listeners.add(listener);
      return () => listeners.delete(listener);
    },
    getState() {
      return state;
    },
    setState(newState) {
      state = { ...state, ...newState };
      listeners.forEach(listener => listener());
    }
  };
})();
This code creates an external store for the form state with subscribe, getState, and setState methods.
import React from 'react';
import { useSyncExternalStore } from 'react';

function useExternalFormState() {
  const getState = React.useCallback(() => formStateStore.getState(), []);

  const subscribe = React.useCallback(
    (onStoreChange) => {
      return formStateStore.subscribe(onStoreChange);
    },
    []
  );

  return useSyncExternalStore(subscribe, getState);
}
This hook uses useSyncExternalStore to sync the form state with the external store.
function FormComponent() {
  const { name, email } = useExternalFormState();

  const handleChange = (event) => {
    const { name, value } = event.target;
    formStateStore.setState({ [name]: value });
  };

  return (
    <form>
      <input
        type='text'
        name='name'
        value={name}
        onChange={handleChange}
      />
      <input
        type='email'
        name='email'
        value={email}
        onChange={handleChange}
      />
      {/* Add other form fields here */}
    </form>
  );
}
This functional component renders a form and binds its state to the external store using the useExternalFormState hook.