restate / v1.0.0
บันทึกเมื่อคุณตัดสินใจ
เก็บ store ไว้ใน IndexedDB หรือ MMKV โหลดครั้งเดียวตอนเริ่มต้น บันทึกโดยตรงหรืออัตโนมัติ และแสดงการเปลี่ยนแปลงที่ยังไม่บันทึก
ในหน้านี้
การประกาศ store แบบบันทึกรอครั้งเดียวตอนเริ่มต้นบันทึก ยกเลิก และรีเซ็ตแสดงการเปลี่ยนแปลงที่ยังไม่บันทึกและความคืบหน้าลองดูบันทึกอัตโนมัติก่อนปิดหน้าการจัดการข้อผิดพลาดของที่จัดเก็บข้อมูลการประกาศ store แบบบันทึก
เปลี่ยน restate เป็น persistedRestate แล้วกำหนด key คอมโพเนนต์ยังใช้ hook และ set ตัวเดิม
ค่าที่บันทึกไว้จะถูกกู้คืนอัตโนมัติหลังสร้าง การแก้ไขเปลี่ยนหน่วยความจำ จะไม่มีอะไรถูกเขียนจนกว่าคุณจะบันทึกหรือเปิด autoSave
import { persistedRestate } from '@kkwaenggwari/restate';
export const useDraft = persistedRestate('', {
key: 'article-draft',
validate: (value) => typeof value === 'string',
});รอครั้งเดียวตอนเริ่มต้น
ที่จุดเริ่มต้นฝั่งไคลเอนต์ ให้ import แอปและ store ของมัน แล้วรอ restateManager.ready ก่อนเรนเดอร์ จากนั้นคอมโพเนนต์อ่านค่าที่บันทึกไว้ได้โดยตรง
ที่จัดเก็บข้อมูลที่ใช้ไม่ได้ เช่น ตอนเรนเดอร์ฝั่งเซิร์ฟเวอร์หรือในเบราว์เซอร์ที่บล็อกไว้ ไม่ถือเป็นข้อผิดพลาด store แบบนั้นทำงานในหน่วยความจำ 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 ส่วน scope ของคอมโพเนนต์จะเขียนการเปลี่ยนแปลงที่ค้างอยู่ตอน unmount
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 และสำหรับ store แบบบันทึกจะมี 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'}".`);
}