自動保存パターン
:LiTarget: 用途
フォーム入力を debounce してバックエンドに自動保存するパターン。
:LiSparkle: 特徴
- debounce
- 保存ステータス表示
- エラーリトライ
:LiCode: コード(コピペ用)
import { useEffect, useRef, useState } from 'react';
// 自動保存フック(debounce + ステータス管理)
type SaveStatus = 'idle' | 'saving' | 'saved' | 'error';
export function useAutoSave<T>(
value: T,
save: (v: T) => Promise<void>,
delay = 1000,
) {
const [status, setStatus] = useState<SaveStatus>('idle');
const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
const initial = useRef(true);
useEffect(() => {
if (initial.current) { initial.current = false; return; }
if (timer.current) clearTimeout(timer.current);
setStatus('idle');
timer.current = setTimeout(async () => {
setStatus('saving');
try {
await save(value);
setStatus('saved');
setTimeout(() => setStatus('idle'), 1500);
} catch {
setStatus('error');
}
}, delay);
return () => { if (timer.current) clearTimeout(timer.current); };
}, [value, delay, save]);
return status;
}
// 使い方:
// const status = useAutoSave(content, (c) => api.saveDoc(docId, c));
// <span>{status === 'saving' ? '保存中…' : status === 'saved' ? '保存済' : ''}</span>
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加