restate / v1.0.0
कंपोनेंट का अपना स्टेट
हर दस्तावेज़, डायलॉग या अनुरोध को अपने स्टोर दें, जो कंपोनेंट के साथ बनें और उसके अनमाउंट होने पर छूट जाएँ।
इस पेज पर
useRestateScopefactory के नियमprops से शुरुआती मानसर्वर रेंडरिंगदस्तावेज़ के सहेजे गए डेटा का इंतज़ारआज़माएँReact के बाहर के मालिकuseRestateScope
factory स्टोर घोषित करके लौटाती है। restate परिणाम को रेंडर के बीच रखता है और कंपोनेंट अनमाउंट होने पर scope नष्ट करता है। कोई क्लोज़ फ़ंक्शन या सफ़ाई वाला effect नहीं लिखना पड़ता।
दो Document एलिमेंट के स्टेट अलग-अलग हैं। दस्तावेज़ को बच्चों के साथ साझा करने के लिए लौटाए गए हुक props या अपने context से दें।
import { restate, useRestateScope } from '@kkwaenggwari/restate';
function Document() {
const { useDraft, useSelection } = useRestateScope((scope) => ({
useDraft: restate('', { scope }),
useSelection: restate(0, { scope }),
}));
const text = useDraft();
const selection = useSelection();
return (
<section>
<input value={text} onChange={(event) => useDraft.set(event.target.value)} />
<button onClick={() => useSelection.set((n) => n + 1)}>Selection: {selection}</button>
</section>
);
}factory के नियम
React factory को कई बार कॉल करके परिणाम फेंक सकता है, इसलिए उसे सिंक्रोनस और शुद्ध रखें।
- स्टोर factory में घोषित करें; लौटाए गए हुक कंपोनेंट के शीर्ष स्तर पर कॉल करें।
- शुरुआती props एक बार पढ़े जाते हैं, जैसे useState के इनिशियलाइज़र में।
- जब किसी दूसरे दस्तावेज़ को नया स्टेट चाहिए, तो कंपोनेंट को key दें।
- factory के बिना useRestateScope() एक स्थिर scope लौटाता है, उन स्टोर के लिए जिन्हें आप बाद में effect या हैंडलर में बनाते हैं।
props से शुरुआती मान
props को शुरुआती मान के रूप में इस्तेमाल करें, और किसी दूसरे दस्तावेज़ के साथ फिर से शुरू करने के लिए React की key।
function Editor({ document }) {
// The initial value is captured once, like a useState initializer.
const useTitle = useRestateScope((scope) => restate(document.title, { scope }));
const title = useTitle();
return <input value={title} onChange={(event) => useTitle.set(event.target.value)} />;
}
// A different document gets fresh state.
<Editor key={document.id} document={document} />;सर्वर रेंडरिंग
सर्वर रूट में डेटा लोड करें और उसे prop के रूप में दें। शुरुआती मान ही सर्वर स्नैपशॉट भी है। Next.js App Router में यह हुक Client Component में आता है, जो फिर भी सर्वर पर रेंडर होता है।
'use client';
import { restate, useRestateScope } from '@kkwaenggwari/restate';
export default function Profile({ user }) {
const useProfile = useRestateScope((scope) => restate(user, { scope }));
const profile = useProfile();
return <p>{profile.name}</p>;
}दस्तावेज़ के सहेजे गए डेटा का इंतज़ार
scope के सहेजे गए स्टोर क्लाइंट पर कंपोनेंट के commit होने पर वापस लाना शुरू करते हैं और वैश्विक restateManager.ready का हिस्सा नहीं होते। लोडिंग सीमा के भीतर scope के अपने manager.ready का इंतज़ार करें।
import { useEffect, useState } from 'react';
import { persistedRestate, useRestateScope } from '@kkwaenggwari/restate';
function Document({ documentId }) {
const { manager, useDraft } = useRestateScope((scope) => ({
manager: scope.manager,
useDraft: persistedRestate('', { scope, namespace: 'documents', key: documentId }),
}));
const [state, setState] = useState('loading');
useEffect(() => {
let active = true;
manager.ready.then(
() => active && setState('ready'),
() => active && setState('error'),
);
return () => {
active = false;
};
}, [manager]);
if (state === 'error') return <p>Could not load this document.</p>;
if (state === 'loading') return <p>Loading document…</p>;
return <Editor useDraft={useDraft} />;
}आज़माएँ
दस्तावेज़ खोलें और बंद करें, और देखें कि उनका स्टेट फिर से कैसे शुरू होता है।
उदाहरण तैयार हो रहा है…
React के बाहर के मालिक
जब स्टेट किसी सर्विस या सर्वर अनुरोध का हो, तो scope ख़ुद बनाएँ और अंत में destroy() कॉल करें। scope नष्ट करने से सहेजे गए रिकॉर्ड कभी नहीं मिटते।
import { createRestateScope, persistedRestate } from '@kkwaenggwari/restate';
export function createDocument(documentId) {
const scope = createRestateScope();
const useDraft = persistedRestate('', {
scope,
namespace: 'documents',
key: documentId,
});
return {
useDraft,
manager: scope.manager,
save: () => scope.manager.saveAll(),
destroy: () => scope.destroy(),
};
}