restate / v1.0.0
اشترك فقط فيما تحتاجه
اختر الجزء من المخزن الذي يعتمد عليه كل مكوّن، وقارن الكائنات عبر shallow، واجمع التغييرات عبر batch، واربط الأحداث الخارجية.
في هذه الصفحة
مرّر selectorجرّبهاختيار عدة حقول عبر shallowاكتب دالة مقارنة خاصة بكجمع التغييرات عبر batchالاشتراك خارج Reactربط الأحداث الخارجيةمرّر selector
استدعِ الخطّاف بدالة تختار ما يحتاجه المكوّن. بعد كل تغيير، ينفّذ restate الـ selector ويقارن النتيجة بالسابقة عبر Object.is. إذا تساوتا، لا يُعاد عرض المكوّن.
تتغيّر البطاقة. هل يُعاد عرض ItemCount؟
لا. ما زال الـ selector الخاص به يعيد عدد المنتجات نفسه، فالاختيار متساوٍ ولا يُطلب من React عرضه.
const useCart = restate({ items: ['Book'], coupon: '', note: '' });
function ItemCount() {
// Re-renders only when the number of items changes.
const count = useCart((cart) => cart.items.length);
return <p>{count} items</p>;
}جرّبه
غيّر الحقول وراقب عدّادات العرض. أوقف shallow لترى selector يعيد كائنًا جديدًا في كل مرة.
جارٍ تجهيز المثال…
اختيار عدة حقول عبر shallow
الـ selector الذي يبني كائنًا يعيد كائنًا جديدًا في كل مرة، فيرى Object.is تغييرًا دائمًا. مرّر shallow وسيطًا ثانيًا: فهو يقارن حقول الكائن الخاصة بعمق مستوى واحد.
يقارن shallow أيضًا عناصر المصفوفات وMap وSet بعمق مستوى واحد.
import { restate, shallow } from '@kkwaenggwari/restate';
function CartSummary() {
const { count, coupon } = useCart(
(cart) => ({ count: cart.items.length, coupon: cart.coupon }),
shallow,
);
return (
<p>
{count} items · {coupon || 'no coupon'}
</p>
);
}اكتب دالة مقارنة خاصة بك
أي دالة (left, right) => boolean تصلح وسيطًا ثانيًا. استخدمها حين لا يكفي shallow، مثل مقارنة قائمة حسب id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);جمع التغييرات عبر batch
كل set يُشعر المشتركين فورًا. حين يغيّر إجراء واحد عدة مخازن، غلّفه في batch: تُحدَّث الذاكرة فورًا، ويعمل المشتركون مرة واحدة بعد الاستدعاء الراجع.
import { batch } from '@kkwaenggwari/restate';
function checkout() {
batch(() => {
useCart.set((cart) => ({ ...cart, items: [] }));
useOrder.set((order) => ({ ...order, status: 'paid' }));
});
// Subscribers run once, after both stores changed.
}الاشتراك خارج React
لا يستدعيك subscribeSelector إلا عندما تتغيّر القيمة المختارة، مع دالة المقارنة الاختيارية نفسها.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);ربط الأحداث الخارجية
يمكن أن يكون الوسيط الثاني لـ restate دالة updater. تبدأ حين يبدأ أول مكوّن أو مشترك بالاستماع، ويعمل تنظيفها حين يتوقف آخرهم، فتبقى أحداث المتصفح أو المقابس أو المستشعرات موصولة فقط ما دامت مطلوبة.
استخدم start() وstop() للتحكم فيها يدويًا.
import { restate } from '@kkwaenggwari/restate';
// Listens while at least one component or subscriber uses the store.
export const useOnline = restate(true, ({ setState }) => {
const update = () => setState(navigator.onLine);
window.addEventListener('online', update);
window.addEventListener('offline', update);
update();
return () => {
window.removeEventListener('online', update);
window.removeEventListener('offline', update);
};
});