restate / v1.0.0
احفظ حين تقرّر
احتفظ بمخزن في IndexedDB أو MMKV، وحمّله مرة واحدة عند البدء، واحفظ صراحةً أو تلقائيًا، واعرض التعديلات غير المحفوظة.
في هذه الصفحة
تعريف مخزن محفوظالانتظار مرة واحدة عند البدءالحفظ والتراجع وإعادة الضبطعرض التعديلات غير المحفوظة والتقدّمجرّبهالحفظ التلقائيقبل إغلاق الصفحةالتعامل مع أخطاء التخزينتعريف مخزن محفوظ
استبدل restate بـ persistedRestate وأعطه key. تواصل المكوّنات استخدام الخطّاف نفسه وset نفسه.
تُستعاد القيمة المحفوظة تلقائيًا بعد الإنشاء. التعديل يغيّر الذاكرة؛ ولا يُكتب شيء حتى تحفظ أو تفعّل autoSave.
import { persistedRestate } from '@kkwaenggwari/restate';
export const useDraft = persistedRestate('', {
key: 'article-draft',
validate: (value) => typeof value === 'string',
});الانتظار مرة واحدة عند البدء
في نقطة دخول العميل، استورد التطبيق ومخازنه، ثم انتظر restateManager.ready قبل العرض. من هناك يمكن للمكوّنات قراءة القيم المحفوظة مباشرة.
التخزين غير المتاح، كما في العرض على الخادم أو في متصفح يحظره، ليس خطأً: تعمل تلك المخازن في الذاكرة. لا يُرفض ready إلا حين يتعذّر قراءة السجلات أو ترحيلها أو التحقق منها.
import { createRoot } from 'react-dom/client';
import { restateManager } from '@kkwaenggwari/restate';
import App from './App';
async function start() {
const root = createRoot(document.getElementById('root'));
try {
await restateManager.ready;
root.render(<App />);
} catch (error) {
root.render(<p>Could not load saved data.</p>);
console.error(error);
}
}
start();الحفظ والتراجع وإعادة الضبط
يكتب save القيمة الحالية، ويعيد restore القيمة المحفوظة، ويمسح resetAll الذاكرة والتخزين معًا. كل منها يعيد Promise.
await useDraft.save(); // write the current value
await useDraft.restore(); // return to the saved value
await useDraft.resetAndClearStorage(); // initial value in memory, record removedعرض التعديلات غير المحفوظة والتقدّم
يُعاد عرض useStatus حين تتغيّر حالة الحفظ. يكون dirty مساويًا لـ true ما دامت الذاكرة تختلف عن آخر قيمة حُمّلت أو حُفظت أو استُعيدت. ويسمّي operation عملية التخزين الجارية.
مرّر selector لإعادة العرض فقط حين يتغيّر حقل واحد.
function SaveButton() {
const { dirty, operation, error } = useDraft.useStatus();
const saving = operation === 'save';
return (
<>
<button disabled={!dirty || saving} onClick={() => useDraft.save().catch(() => {})}>
{saving ? 'Saving…' : 'Save'}
</button>
{error != null && <p>Could not save your draft.</p>}
</>
);
}جرّبه
اكتب، وارفع زمن استجابة التخزين، واحفظ. أعد تشغيل المثال لترى المسودة المحفوظة مستعادة.
جارٍ تجهيز المثال…
الحفظ التلقائي
للإعدادات والمسودات التي يجب أن تُحفظ دائمًا، فعّله مرة واحدة. يحفظ autoSave: true بعد كل تغيير؛ وينتظر { delayMs } حتى تتوقف التعديلات.
دفعة من التعديلات تصبح كتابة واحدة، والعودة إلى القيمة المحفوظة لا تكتب شيئًا. تظهر الأخطاء في status().error. ونطاق المكوّن يكتب التعديل المعلّق عند إزالته.
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });
export const useDraft = persistedRestate('', {
key: 'article-draft',
autoSave: { delayMs: 500 },
});قبل إغلاق الصفحة
اقرأ الحالة نفسها خارج React. حذّر قبل المغادرة إن وُجدت تعديلات غير محفوظة، أو احفظ كل شيء حين تُخفى الصفحة.
window.addEventListener('beforeunload', (event) => {
if (useDraft.status().dirty) event.preventDefault();
});
window.addEventListener('pagehide', () => {
restateManager.saveAll();
});التعامل مع أخطاء التخزين
أخطاء التخزين ترفض Promise العملية. لكل خطأ في restate قيمة code، وللمخازن المحفوظة أيضًا key السجل.
try {
await useDraft.save();
} catch (error) {
if (error.code === 'STORAGE_UNAVAILABLE') showNotice('Saving is off in this browser.');
else if (error.code === 'STORAGE_VALUE_TOO_LARGE') showNotice('This draft is too large.');
else showNotice(`Could not save "${error.key ?? 'draft'}".`);
}