restate / v1.0.0

บันทึกเมื่อคุณตัดสินใจ

เก็บ store ไว้ใน IndexedDB หรือ MMKV โหลดครั้งเดียวตอนเริ่มต้น บันทึกโดยตรงหรืออัตโนมัติ และแสดงการเปลี่ยนแปลงที่ยังไม่บันทึก

ในหน้านี้การประกาศ store แบบบันทึกรอครั้งเดียวตอนเริ่มต้นบันทึก ยกเลิก และรีเซ็ตแสดงการเปลี่ยนแปลงที่ยังไม่บันทึกและความคืบหน้าลองดูบันทึกอัตโนมัติก่อนปิดหน้าการจัดการข้อผิดพลาดของที่จัดเก็บข้อมูล

การประกาศ store แบบบันทึก

เปลี่ยน restate เป็น persistedRestate แล้วกำหนด key คอมโพเนนต์ยังใช้ hook และ set ตัวเดิม

ค่าที่บันทึกไว้จะถูกกู้คืนอัตโนมัติหลังสร้าง การแก้ไขเปลี่ยนหน่วยความจำ จะไม่มีอะไรถูกเขียนจนกว่าคุณจะบันทึกหรือเปิด autoSave

JavaScript / JSX
import { persistedRestate } from '@kkwaenggwari/restate';

export const useDraft = persistedRestate('', {
  key: 'article-draft',
  validate: (value) => typeof value === 'string',
});

รอครั้งเดียวตอนเริ่มต้น

ที่จุดเริ่มต้นฝั่งไคลเอนต์ ให้ import แอปและ store ของมัน แล้วรอ restateManager.ready ก่อนเรนเดอร์ จากนั้นคอมโพเนนต์อ่านค่าที่บันทึกไว้ได้โดยตรง

ที่จัดเก็บข้อมูลที่ใช้ไม่ได้ เช่น ตอนเรนเดอร์ฝั่งเซิร์ฟเวอร์หรือในเบราว์เซอร์ที่บล็อกไว้ ไม่ถือเป็นข้อผิดพลาด store แบบนั้นทำงานในหน่วยความจำ ready จะถูกปฏิเสธก็ต่อเมื่ออ่าน ย้ายรูปแบบ หรือตรวจสอบระเบียนไม่ได้เท่านั้น

JavaScript / JSX
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

JavaScript / JSX
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 เพื่อให้เรนเดอร์ใหม่เฉพาะเมื่อฟิลด์เดียวเปลี่ยน

JavaScript / JSX
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

JavaScript / JSX
export const useTheme = persistedRestate('light', { key: 'theme', autoSave: true });

export const useDraft = persistedRestate('', {
  key: 'article-draft',
  autoSave: { delayMs: 500 },
});

ก่อนปิดหน้า

อ่านสถานะเดียวกันนอก React เตือนเรื่องการเปลี่ยนแปลงที่ยังไม่บันทึกก่อนออก หรือบันทึกทั้งหมดเมื่อหน้าถูกซ่อน

JavaScript / JSX
window.addEventListener('beforeunload', (event) => {
  if (useDraft.status().dirty) event.preventDefault();
});

window.addEventListener('pagehide', () => {
  restateManager.saveAll();
});

การจัดการข้อผิดพลาดของที่จัดเก็บข้อมูล

ข้อผิดพลาดของที่จัดเก็บข้อมูลทำให้ Promise ของการทำงานถูกปฏิเสธ ข้อผิดพลาดของ restate ทุกตัวมี code และสำหรับ store แบบบันทึกจะมี key ของระเบียนด้วย

JavaScript / JSX
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'}".`);
}

ค้นหาเอกสาร

ค้นหาในชื่อเรื่อง คำอธิบาย และเนื้อหาของคู่มือทั้งหมด