React आणि React Native साठी स्टेट · 1.0
स्टेट सामायिक करा.एक हुक.झाले.
एका ओळीत स्टोअर घोषित करा आणि Provider, action किंवा reducer शिवाय कोणत्याही कंपोनंटमध्ये वापरा. कंपोनंटने निवडलेले मूल्य बदलले तरच तो पुन्हा रेंडर होतो; सेव्ह तुम्ही ठरवाल तेव्हा होते.
npm install @kkwaenggwari/restateथेट — खरा restate स्टोअर
useCart.set(cart => ({ ...cart, items: cart.items + 1, total: cart.total + 12 }))items आणि total बदलतात: तीन कार्ड रेंडर होतात, गिफ्ट कार्ड स्थिर राहते.
01 — सोपे
तेच वैशिष्ट्य, कमी संकल्पना.
एकाच कामाची चार अंमलबजावणी शेजारी शेजारी. आकडे इथे दाखवलेल्या कोडमधून येतात आणि ही साइट build होताना मोजले जातात.
सामायिक काउंटर
दोन कंपोनंट एकच संख्या वाचतात आणि अद्ययावत करतात.
Redux Toolkit अद्यतने slice आणि action मध्ये संघटित करते आणि React context द्वारे दिलेल्या स्टोअरला पाठवते. उत्कृष्ट DevTools आणि मोठ्या संघांसाठी कठोर, अंदाज बांधता येणारा अद्यतन प्रवाह.
Zustand create() ने स्टोअर हुक तयार करते आणि setState ने बदलते. अतिशय लहान आणि लवचिक, persistence व DevTools साठी middleware सह.
Jotai atom आणि व्युत्पन्न atom जोडते, ऐच्छिकपणे Provider मध्ये. अनेक लहान स्टेट तुकड्यांमधील सूक्ष्म अवलंबित्वे.
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useDispatch, useSelector } from 'react-redux';
const slice = createSlice({
name: 'count',
initialState: 0,
reducers: { increment: (count) => count + 1 },
});
const store = configureStore({
reducer: { count: slice.reducer },
});
function Counter() {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();
return <button onClick={() => dispatch(slice.actions.increment())}>{count}</button>;
}
export default function App() {
return (
<Provider store={store}>
<Counter />
<Counter />
</Provider>
);
}import { create } from 'zustand';
const useCount = create(() => ({ count: 0 }));
const increment = () =>
useCount.setState((s) => ({
count: s.count + 1,
}));
function Counter() {
const count = useCount((s) => s.count);
return <button onClick={increment}>{count}</button>;
}
export default function App() {
return (
<>
<Counter />
<Counter />
</>
);
}import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount((n) => n + 1)}>{count}</button>;
}
export default function App() {
return (
<>
<Counter />
<Counter />
</>
);
}restate एकच घोषणा स्टोअर आणि हुक दोन्ही बनते.
import { restate } from '@kkwaenggwari/restate';
const useCount = restate(0);
function Counter() {
const count = useCount();
return <button onClick={() => useCount.set((n) => n + 1)}>{count}</button>;
}
export default function App() {
return (
<>
<Counter />
<Counter />
</>
);
}या कामासाठी Zustand आणि Jotai देखील लहान आहेत आणि Provider शिवाय चालतात. सेव्ह आणि प्रति-दस्तऐवज स्टेट जोडल्यावर फरक वाढतो.
फील्ड निवडणे
फक्त मजकूर बदलल्यावर शीर्षक कंपोनंट रेंडर होऊ नये.
Redux Toolkit अद्यतने slice आणि action मध्ये संघटित करते आणि React context द्वारे दिलेल्या स्टोअरला पाठवते. उत्कृष्ट DevTools आणि मोठ्या संघांसाठी कठोर, अंदाज बांधता येणारा अद्यतन प्रवाह.
Zustand create() ने स्टोअर हुक तयार करते आणि setState ने बदलते. अतिशय लहान आणि लवचिक, persistence व DevTools साठी middleware सह.
Jotai atom आणि व्युत्पन्न atom जोडते, ऐच्छिकपणे Provider मध्ये. अनेक लहान स्टेट तुकड्यांमधील सूक्ष्म अवलंबित्वे.
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useSelector } from 'react-redux';
const article = createSlice({
name: 'article',
initialState: { title: 'Hello', body: '' },
reducers: {
editBody: (i) => {
i.body += '!';
},
editTitle: (i) => {
i.title += '!';
},
},
});
const store = configureStore({ reducer: article.reducer });
function Title() {
const title = useSelector((i) => i.title);
return <h3>{title}</h3>;
}
export default function App() {
return (
<Provider store={store}>
<Title />
<button onClick={() => store.dispatch(article.actions.editBody())}>body + !</button>
<button onClick={() => store.dispatch(article.actions.editTitle())}>title + !</button>
</Provider>
);
}import { create } from 'zustand';
const useArticle = create(() => ({ title: 'Hello', body: '' }));
function Title() {
const title = useArticle((i) => i.title);
return <h3>{title}</h3>;
}
export default function App() {
return (
<>
<Title />
<button
onClick={() =>
useArticle.setState((i) => ({
body: i.body + '!',
}))
}
>
body + !
</button>
<button
onClick={() =>
useArticle.setState((i) => ({
title: i.title + '!',
}))
}
>
title + !
</button>
</>
);
}import { atom, useAtomValue, useSetAtom } from 'jotai';
const articleAtom = atom({ title: 'Hello', body: '' });
const titleAtom = atom((get) => get(articleAtom).title);
function Title() {
const title = useAtomValue(titleAtom);
return <h3>{title}</h3>;
}
export default function App() {
const setArticle = useSetAtom(articleAtom);
return (
<>
<Title />
<button
onClick={() =>
setArticle((i) => ({
...i,
body: i.body + '!',
}))
}
>
body + !
</button>
<button
onClick={() =>
setArticle((i) => ({
...i,
title: i.title + '!',
}))
}
>
title + !
</button>
</>
);
}restate तुम्ही आधीच वापरत असलेल्या त्याच हुकला selector द्या.
import { restate } from '@kkwaenggwari/restate';
const useArticle = restate({ title: 'Hello', body: '' });
function Title() {
const title = useArticle((i) => i.title);
return <h3>{title}</h3>;
}
export default function App() {
return (
<>
<Title />
<button
onClick={() =>
useArticle.set((i) => ({
...i,
body: i.body + '!',
}))
}
>
body + !
</button>
<button
onClick={() =>
useArticle.set((i) => ({
...i,
title: i.title + '!',
}))
}
>
title + !
</button>
</>
);
}इथली सर्व साधने निवडू शकतात. restate वेगळ्या selector हुक किंवा व्युत्पन्न atom ऐवजी तोच हुक कॉल वापरते.
मसुदा सेव्ह करणे
सुरुवातीला सेव्ह केलेला मसुदा पुनर्संचयित करा, क्लिकवर सेव्ह करा आणि सेव्ह होत आहे, सेव्ह न झालेले आणि अयशस्वी स्थिती दाखवा.
Redux Toolkit अद्यतने slice आणि action मध्ये संघटित करते आणि React context द्वारे दिलेल्या स्टोअरला पाठवते. उत्कृष्ट DevTools आणि मोठ्या संघांसाठी कठोर, अंदाज बांधता येणारा अद्यतन प्रवाह.
Zustand create() ने स्टोअर हुक तयार करते आणि setState ने बदलते. अतिशय लहान आणि लवचिक, persistence व DevTools साठी middleware सह.
Jotai atom आणि व्युत्पन्न atom जोडते, ऐच्छिकपणे Provider मध्ये. अनेक लहान स्टेट तुकड्यांमधील सूक्ष्म अवलंबित्वे.
import { useEffect, useState } from 'react';
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useSelector } from 'react-redux';
function openDraftDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('draft-example', 1);
let blocked = false;
request.onupgradeneeded = () => {
request.result.createObjectStore('drafts');
};
request.onblocked = () => {
blocked = true;
reject(new Error('Close other tabs to upgrade storage'));
};
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const db = request.result;
if (blocked) {
db.close();
return;
}
db.onversionchange = () => db.close();
resolve(db);
};
});
}
async function storedDraft(mode, text) {
const db = await openDraftDB();
try {
return await new Promise((resolve, reject) => {
const tx = db.transaction('drafts', mode);
const store = tx.objectStore('drafts');
const request = mode === 'readonly' ? store.get('draft') : store.put(text, 'draft');
tx.oncomplete = () => resolve(request.result);
tx.onabort = () => reject(tx.error || new Error('Storage aborted'));
});
} finally {
db.close();
}
}
const draft = createSlice({
name: 'draft',
initialState: '',
reducers: { edit: (_, action) => action.payload },
});
const store = configureStore({ reducer: { draft: draft.reducer } });
const hydrated = storedDraft('readonly').then((saved) => {
if (saved === undefined) return;
if (typeof saved !== 'string') throw new Error('Invalid draft');
const value = saved;
store.dispatch(draft.actions.edit(value));
});
// Observe errors immediately, even before the component mounts.
hydrated.catch(() => {});
function DraftEditor() {
const text = useSelector((state) => state.draft);
const [ready, setReady] = useState(false);
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState('Loading');
useEffect(() => {
let active = true;
hydrated.then(
() => {
if (active) {
setReady(true);
setMessage('Ready');
}
},
() => {
if (active) setMessage('Storage error');
},
);
return () => {
active = false;
};
}, []);
async function save() {
setSaving(true);
try {
await storedDraft('readwrite', store.getState().draft);
setMessage('Saved');
} catch {
setMessage('Save failed');
} finally {
setSaving(false);
}
}
return (
<>
<label>
Draft
<textarea
value={text}
disabled={!ready || saving}
onChange={(event) => {
const value = event.target.value;
store.dispatch(draft.actions.edit(value));
setMessage('Edited');
}}
/>
</label>
<output>{text}</output>
<button disabled={!ready || saving} onClick={save}>
Save
</button>
<p>{message}</p>
</>
);
}
export default function App() {
return (
<Provider store={store}>
<DraftEditor />
</Provider>
);
}import { useEffect, useState } from 'react';
import { create } from 'zustand';
function openDraftDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('draft-example', 1);
let blocked = false;
request.onupgradeneeded = () => {
request.result.createObjectStore('drafts');
};
request.onblocked = () => {
blocked = true;
reject(new Error('Close other tabs to upgrade storage'));
};
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const db = request.result;
if (blocked) {
db.close();
return;
}
db.onversionchange = () => db.close();
resolve(db);
};
});
}
async function storedDraft(mode, text) {
const db = await openDraftDB();
try {
return await new Promise((resolve, reject) => {
const tx = db.transaction('drafts', mode);
const store = tx.objectStore('drafts');
const request = mode === 'readonly' ? store.get('draft') : store.put(text, 'draft');
tx.oncomplete = () => resolve(request.result);
tx.onabort = () => reject(tx.error || new Error('Storage aborted'));
});
} finally {
db.close();
}
}
const useDraft = create(() => ({ text: '' }));
const hydrated = storedDraft('readonly').then((saved) => {
if (saved === undefined) return;
if (typeof saved !== 'string') throw new Error('Invalid draft');
const value = saved;
useDraft.setState({ text: value });
});
// Observe errors immediately, even before the component mounts.
hydrated.catch(() => {});
function DraftEditor() {
const text = useDraft((state) => state.text);
const [ready, setReady] = useState(false);
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState('Loading');
useEffect(() => {
let active = true;
hydrated.then(
() => {
if (active) {
setReady(true);
setMessage('Ready');
}
},
() => {
if (active) setMessage('Storage error');
},
);
return () => {
active = false;
};
}, []);
async function save() {
setSaving(true);
try {
await storedDraft('readwrite', useDraft.getState().text);
setMessage('Saved');
} catch {
setMessage('Save failed');
} finally {
setSaving(false);
}
}
return (
<>
<label>
Draft
<textarea
value={text}
disabled={!ready || saving}
onChange={(event) => {
const value = event.target.value;
useDraft.setState({ text: value });
setMessage('Edited');
}}
/>
</label>
<output>{text}</output>
<button disabled={!ready || saving} onClick={save}>
Save
</button>
<p>{message}</p>
</>
);
}
export default function App() {
return <DraftEditor />;
}import { useEffect, useState } from 'react';
import { atom, createStore, useAtomValue } from 'jotai';
function openDraftDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('draft-example', 1);
let blocked = false;
request.onupgradeneeded = () => {
request.result.createObjectStore('drafts');
};
request.onblocked = () => {
blocked = true;
reject(new Error('Close other tabs to upgrade storage'));
};
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const db = request.result;
if (blocked) {
db.close();
return;
}
db.onversionchange = () => db.close();
resolve(db);
};
});
}
async function storedDraft(mode, text) {
const db = await openDraftDB();
try {
return await new Promise((resolve, reject) => {
const tx = db.transaction('drafts', mode);
const store = tx.objectStore('drafts');
const request = mode === 'readonly' ? store.get('draft') : store.put(text, 'draft');
tx.oncomplete = () => resolve(request.result);
tx.onabort = () => reject(tx.error || new Error('Storage aborted'));
});
} finally {
db.close();
}
}
const draftAtom = atom('');
const store = createStore();
const hydrated = storedDraft('readonly').then((saved) => {
if (saved === undefined) return;
if (typeof saved !== 'string') throw new Error('Invalid draft');
const value = saved;
store.set(draftAtom, value);
});
// Observe errors immediately, even before the component mounts.
hydrated.catch(() => {});
function DraftEditor() {
const text = useAtomValue(draftAtom, { store });
const [ready, setReady] = useState(false);
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState('Loading');
useEffect(() => {
let active = true;
hydrated.then(
() => {
if (active) {
setReady(true);
setMessage('Ready');
}
},
() => {
if (active) setMessage('Storage error');
},
);
return () => {
active = false;
};
}, []);
async function save() {
setSaving(true);
try {
await storedDraft('readwrite', store.get(draftAtom));
setMessage('Saved');
} catch {
setMessage('Save failed');
} finally {
setSaving(false);
}
}
return (
<>
<label>
Draft
<textarea
value={text}
disabled={!ready || saving}
onChange={(event) => {
const value = event.target.value;
store.set(draftAtom, value);
setMessage('Edited');
}}
/>
</label>
<output>{text}</output>
<button disabled={!ready || saving} onClick={save}>
Save
</button>
<p>{message}</p>
</>
);
}
export default function App() {
return <DraftEditor />;
}restate persistedRestate आपोआप पुनर्संचयित करते; useStatus सेव्ह, सेव्ह न झालेले बदल आणि त्रुटी कळवते.
import { persistedRestate } from '@kkwaenggwari/restate';
const useDraft = persistedRestate('', {
key: 'draft',
validate: (value) => typeof value === 'string',
});
export default function App() {
const text = useDraft();
const { dirty, operation, error } = useDraft.useStatus();
const saving = operation === 'save';
const message = error ? 'Save failed' : saving ? 'Saving…' : dirty ? 'Edited' : 'Saved';
return (
<>
<label>
Draft
<textarea value={text} onChange={(event) => useDraft.set(event.target.value)} />
</label>
<output>{text}</output>
<button disabled={saving} onClick={() => useDraft.save().catch(() => {})}>
Save
</button>
<p>{message}</p>
</>
);
}इतर आवृत्त्या तोच IndexedDB कोड हाताने लिहितात. त्यांचे persistence middleware किंवा स्टोरेज साधने अडॅप्टरसह तो कमी करू शकतात; तो कोड इथे मोजलेला नाही.
प्रति-दस्तऐवज स्टेट
दोन दस्तऐवज वेगवेगळे स्टेट ठेवतात; एक बंद केल्यावर ते मोकळे होते.
Redux Toolkit अद्यतने slice आणि action मध्ये संघटित करते आणि React context द्वारे दिलेल्या स्टोअरला पाठवते. उत्कृष्ट DevTools आणि मोठ्या संघांसाठी कठोर, अंदाज बांधता येणारा अद्यतन प्रवाह.
Zustand create() ने स्टोअर हुक तयार करते आणि setState ने बदलते. अतिशय लहान आणि लवचिक, persistence व DevTools साठी middleware सह.
Jotai atom आणि व्युत्पन्न atom जोडते, ऐच्छिकपणे Provider मध्ये. अनेक लहान स्टेट तुकड्यांमधील सूक्ष्म अवलंबित्वे.
import { useState } from 'react';
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { Provider, useSelector } from 'react-redux';
const draft = createSlice({
name: 'draft',
initialState: '',
reducers: { edit: (_, action) => action.payload },
});
const selectionSlice = createSlice({
name: 'selection',
initialState: 0,
reducers: { next: (index) => index + 1 },
});
function createDocument() {
return {
store: configureStore({
reducer: {
draft: draft.reducer,
selection: selectionSlice.reducer,
},
}),
};
}
function Document({ doc, name }) {
const text = useSelector((state) => state.draft);
const selection = useSelector((state) => state.selection);
return (
<section>
<label>
{name}
<input
value={text}
onChange={(event) => doc.store.dispatch(draft.actions.edit(event.target.value))}
/>
</label>
<output>{text}</output>
<button onClick={() => doc.store.dispatch(selectionSlice.actions.next())}>
Selection: {selection}
</button>
</section>
);
}
function DocumentSlot({ name }) {
const [doc] = useState(createDocument);
return (
<Provider store={doc.store}>
<Document doc={doc} name={name} />
</Provider>
);
}
export default function App() {
const [leftOpen, setLeftOpen] = useState(true);
return (
<>
<button onClick={() => setLeftOpen((open) => !open)}>
{leftOpen ? 'Close left' : 'Open left'}
</button>
{leftOpen && <DocumentSlot name="Left" />}
<DocumentSlot name="Right" />
</>
);
}import { useState } from 'react';
import { useStore } from 'zustand';
import { createStore } from 'zustand/vanilla';
function createDocument() {
return {
draft: createStore(() => ({ text: '' })),
selection: createStore(() => ({ index: 0 })),
};
}
function Document({ doc, name }) {
const text = useStore(doc.draft, (state) => state.text);
const selection = useStore(doc.selection, (state) => state.index);
return (
<section>
<label>
{name}
<input
value={text}
onChange={(event) => doc.draft.setState({ text: event.target.value })}
/>
</label>
<output>{text}</output>
<button onClick={() => doc.selection.setState((s) => ({ index: s.index + 1 }))}>
Selection: {selection}
</button>
</section>
);
}
function DocumentSlot({ name }) {
const [doc] = useState(createDocument);
return <Document doc={doc} name={name} />;
}
export default function App() {
const [leftOpen, setLeftOpen] = useState(true);
return (
<>
<button onClick={() => setLeftOpen((open) => !open)}>
{leftOpen ? 'Close left' : 'Open left'}
</button>
{leftOpen && <DocumentSlot name="Left" />}
<DocumentSlot name="Right" />
</>
);
}import { useState } from 'react';
import { atom, createStore, useAtomValue } from 'jotai';
const draftAtom = atom('');
const selectionAtom = atom(0);
function createDocument() {
return { store: createStore() };
}
function Document({ doc, name }) {
const text = useAtomValue(draftAtom, { store: doc.store });
const selection = useAtomValue(selectionAtom, { store: doc.store });
return (
<section>
<label>
{name}
<input value={text} onChange={(event) => doc.store.set(draftAtom, event.target.value)} />
</label>
<output>{text}</output>
<button onClick={() => doc.store.set(selectionAtom, (n) => n + 1)}>
Selection: {selection}
</button>
</section>
);
}
function DocumentSlot({ name }) {
const [doc] = useState(createDocument);
return <Document doc={doc} name={name} />;
}
export default function App() {
const [leftOpen, setLeftOpen] = useState(true);
return (
<>
<button onClick={() => setLeftOpen((open) => !open)}>
{leftOpen ? 'Close left' : 'Open left'}
</button>
{leftOpen && <DocumentSlot name="Left" />}
<DocumentSlot name="Right" />
</>
);
}restate useRestateScope स्टोअर तयार करते आणि अनमाउंटनंतर नष्ट करते.
import { useState } from 'react';
import { restate, useRestateScope } from '@kkwaenggwari/restate';
function Document({ name }) {
const doc = useRestateScope((scope) => ({
useDraft: restate('', { scope }),
useSelection: restate(0, { scope }),
}));
const text = doc.useDraft();
const selection = doc.useSelection();
return (
<section>
<label>
{name}
<input value={text} onChange={(event) => doc.useDraft.set(event.target.value)} />
</label>
<output>{text}</output>
<button onClick={() => doc.useSelection.set((n) => n + 1)}>Selection: {selection}</button>
</section>
);
}
export default function App() {
const [leftOpen, setLeftOpen] = useState(true);
return (
<>
<button onClick={() => setLeftOpen((open) => !open)}>
{leftOpen ? 'Close left' : 'Open left'}
</button>
{leftOpen && <Document name="Left" />}
<Document name="Right" />
</>
);
}Jotai मधील Provider किंवा store, किंवा Zustand मधील vanilla store स्टेट वेगळे करू शकतात; ते तुम्ही स्वतः तयार करून जोडता.
हे आकडे कसे मोजले जातात
दाखवलेल्या कोडमधील रिकाम्या नसलेल्या ओळी आणि प्रत्येक स्टेट लायब्ररीतून import केलेली नावे (React import मोजले जात नाहीत). प्रत्येक आवृत्ती तेच UI त्याच स्टोरेज, लोडिंग आणि त्रुटी स्थितींसह रेंडर करते. restate उदाहरणे ॲपच्या प्रवेश बिंदूवर await restateManager.ready असल्याचे गृहीत धरतात. स्रोत प्रत्येक प्रकल्पाच्या अधिकृत दस्तऐवजांशी तपासले आहेत:
- Redux Toolkit — Redux Toolkit · Quick Start, React Redux · useSelector, Redux Toolkit · configureStore. तपासता येणारा एकच action लॉग आणि मोठी middleware परिसंस्था सर्वात महत्त्वाची असल्यास हे निवडा
- Zustand — Zustand · Introduction, Zustand · persist. सर्वात लहान गाभा हवा असेल आणि middleware स्वतः जोडायचे असेल तर हे निवडा
- Jotai — Jotai · atom, Jotai · Storage, Jotai · Provider. तुमचे स्टेट स्वाभाविकपणे लहान व्युत्पन्न मूल्यांचा आलेख असेल तर हे निवडा
02 — वेगवान
फक्त बदललेले रेंडर करा. एकदाच लिहा.
दोन्ही पॅनेल तुमच्या ब्राउझरमध्ये खरे restate पॅकेज चालवतात. क्लिक करा, टाइप करा आणि गणना पाहा.
रेंडर नकाशा
तीच चार फील्ड्स, दोन प्रकारे वाचली जातात. एक फील्ड बदला आणि रेंडर मोजा.
- नाव
- थीम
- काउंटर
- मसुदा
- नाव
- थीम
- काउंटर
- मसुदा
एकत्रित लेखन
autoSave टायपिंगमध्ये विरामाची वाट पाहून एकदाच लिहिते. लागोपाठच्या save() कॉल्स रांगेतील एकच लेखन सामायिक करतात.
persistedRestate('', { key: 'note', autoSave: { delayMs: 400 } });आकडे या पानावरील खऱ्या React रेंडरमधून आणि लेखन मोजणाऱ्या स्टोरेज अडॅप्टरमधून येतात. इतर लायब्ररीही मूल्ये निवडू शकतात; इथे निवडणे हा वाचण्याचा फक्त एक मार्ग आहे.
03 — स्थिर
स्टोरेज अयशस्वी झाले तरी तुमचा डेटा सुरक्षित राहतो.
स्टेट सेव्ह करतानाच हरवते: मंद डिस्क, अवरोधित स्टोरेज, बंद टॅब. ही restate 1.0 ची हमी आहे, सल्ले नाहीत.
- 01
सेव्ह क्रमाने होतात
प्रत्येक स्टोअर स्टोरेज क्रिया एकामागून एक करतो, त्यामुळे मंद सेव्ह कधीही जुन्या मूल्याने नवीन ओव्हरराइट करत नाही.
save() · restore() - 02
प्रलंबित सेव्ह सर्वात नवे मूल्य घेते
दुसरे सेव्ह रांगेत असताना save() कॉल केल्यास ते अतिरिक्त लेखन न साठवता त्यात सामील होते.
save(): Promise<T> - 03
न वाचलेल्या नोंदी कधीही चुकून बदलल्या जात नाहीत
एखादी नोंद लोड झाली नाही तर autoSave आणि एकत्रित सेव्ह तिला हात न लावता LOAD_FAILED कळवतात. फक्त स्पष्ट save() तिला बदलू शकते.
LOAD_FAILED - 04
अनमाउंटनंतरही सेव्ह पूर्ण होते
अनमाउंटपूर्वी मागितलेले सेव्ह पूर्ण होतात. नष्ट झालेल्या स्टोअरवरील नंतरचे लेखन, अनमाउंटनंतरच्या React स्टेटप्रमाणेच, दुर्लक्षित केले जाते.
useRestateScope - 05
स्टोरेज नाही? ॲप तरीही सुरू होते
सर्व्हर रेंडरिंगदरम्यान किंवा स्टोरेज अवरोधित असताना, स्टोअर मेमरीमध्ये चालू राहतात आणि स्टोरेज उपलब्ध नसल्याचे कळवतात.
status().available - 06
त्रुटी काय आणि कुठे ते सांगतात
प्रत्येक restate त्रुटीमध्ये टाइप केलेला कोड आणि त्याच्या नोंदीची key असते, त्यामुळे योग्य संदेश दाखवता येतो.
error.code · error.key
तुमच्या ॲपसोबत वाढते
घोषणा बदला. कंपोनंट तसेच ठेवा.
सेव्ह, स्वयं-सेव्ह आणि प्रमाणीकरण हे एकाच स्टोअरचे पर्याय आहेत. उजवीकडील कंपोनंट कधीही बदलत नाही.
मेमरी
मेमरीमध्ये सामायिक मूल्य.
import { restate } from '@kkwaenggwari/restate'; export const useDraft = restate('');सेव्ह होणारे
आपोआप पुनर्संचयित होते; save() कॉल केल्यावर लिहिले जाते.
import { persistedRestate } from '@kkwaenggwari/restate'; export const useDraft = persistedRestate('', { key: 'draft' });स्वयं-सेव्ह
टायपिंगमध्ये 500 ms विरामानंतर एकदा लिहिले जाते.
import { persistedRestate } from '@kkwaenggwari/restate'; export const useDraft = persistedRestate('', { key: 'draft', autoSave: { delayMs: 500 }, });प्रमाणीकरणासह
जुन्या नोंदी वापरण्यापूर्वी रूपांतरित आणि प्रमाणित केल्या जातात.
import { persistedRestate } from '@kkwaenggwari/restate'; export const useDraft = persistedRestate('', { key: 'draft', autoSave: { delayMs: 500 }, version: 2, migrate: (value) => String(value ?? ''), validate: (value) => typeof value === 'string', });
कंपोनंट — प्रत्येक पायरीवर तोच
function Editor() {
const text = useDraft();
return <textarea value={text} onChange={(event) => useDraft.set(event.target.value)} />;
}React जिथे चालते तिथे चालते
प्रत्येक React वातावरणासाठी एकच पॅकेज.
react >=16.8.0React
React 16.8 आणि नवीन आवृत्त्यांसह, ब्राउझरमध्ये आणि सर्व्हर रेंडरिंगदरम्यान चालते.
react-native-mmkv >=2.0.0React Native
तेच import. react-native-mmkv इन्स्टॉल झाल्यावर सेव्ह MMKV वापरते.
SSRसर्व्हर रेंडरिंग
कंपोनंट स्टोअर props मधून सर्व्हर स्नॅपशॉट घेतात आणि hydration नंतर लोड सुरू करतात.
index.d.tsTypeScript
घोषणा सोबत येतात. सिलेक्टर, स्थिती फील्ड्स आणि त्रुटी कोड टाइप केलेले आहेत.
सुरुवात
एका मिनिटात तुमचे पहिले सामायिक स्टेट.
इन्स्टॉल करा, घोषित करा, वापरा. ॲपला गरज लागेल तेव्हा सेव्ह जोडा.
- 01इन्स्टॉलेशन
npm install @kkwaenggwari/restate - 02स्टोअर घोषित करा
export const useCart = restate({ items: 0, total: 0 }); - 03कोणत्याही कंपोनंटमध्ये वाचा
const items = useCart((cart) => cart.items);
KKWAENGGWARI