Skip to content

React Adapter Guide (@continuejs/react) ​

The @continuejs/react package provides the useDraft hook for React 18 & 19 applications.


Controlled Input Form Example ​

tsx
import React, { useState, useEffect } from 'react';
import { useDraft } from '@continuejs/react';
import '@continuejs/ui';

export function ContactForm() {
  const { hasDraft, restore, draft, lastSaved, clearDraft } = useDraft('contact-form', {
    retention: '7d',
  });

  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: '',
  });

  // Sync state to draft
  useEffect(() => {
    draft.setMultiple(formData);
    draft.save();
  }, [formData, draft]);

  const handleRestore = async () => {
    const saved = await restore();
    if (saved) {
      setFormData({
        name: saved.name || '',
        email: saved.email || '',
        message: saved.message || '',
      });
    }
  };

  return (
    <div className="form-container">
      {hasDraft && (
        <continuejs-banner
          last-saved={lastSaved ? String(lastSaved) : ''}
          ref={(el) => {
            el?.addEventListener('continuejs-restore', handleRestore);
            el?.addEventListener('continuejs-discard', clearDraft);
          }}
        />
      )}

      <form onSubmit={(e) => { e.preventDefault(); clearDraft(); }}>
        <input
          type="text"
          value={formData.name}
          onChange={(e) => setFormData({ ...formData, name: e.target.value })}
        />
        <input
          type="email"
          value={formData.email}
          onChange={(e) => setFormData({ ...formData, email: e.target.value })}
        />
        <textarea
          value={formData.message}
          onChange={(e) => setFormData({ ...formData, message: e.target.value })}
        />
        <button type="submit">Submit</button>
      </form>
    </div>
  );
}

Released under the MIT License.