restate / v1.0.0
Csak arra iratkozzon fel, amire szüksége van
Válassza ki, a store melyik részétől függ az egyes komponensek, hasonlítson objektumokat shallow-val, fogja össze a változásokat batch-csel, és kösse be a külső eseményeket.
Ezen az oldalon
Adjon át egy selectortPróbálja kiTöbb mező kiválasztása shallow-valSaját összehasonlításVáltozások összefogása batch-cselFeliratkozás a Reacten kívülKülső események bekötéseAdjon át egy selectort
Hívja meg a hookot egy függvénnyel, amely kiválasztja, amire a komponensnek szüksége van. Minden változás után a restate lefuttatja a selectort, és az eredményt az előzővel Object.is segítségével hasonlítja össze. Ha egyenlők, a komponens nem renderel.
A kártya változik. Renderel az ItemCount?
Nem. A selectora továbbra is ugyanannyi terméket ad vissza, így a kiválasztás egyenlő, és a Reactet nem kérik renderelésre.
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>;
}Próbálja ki
Módosítsa a mezőket, és figyelje a renderelésszámlálókat. Kapcsolja ki a shallow-t, hogy lásson egy selectort, amely minden alkalommal új objektumot ad vissza.
A példa előkészítése…
Több mező kiválasztása shallow-val
Ha egy selector objektumot épít, minden alkalommal újat ad vissza, így az Object.is mindig változást lát. Adja meg második argumentumként a shallow-t: egy szint mélységig összehasonlítja az objektum saját mezőit.
A shallow egy szint mélységig a tömbök, a Map és a Set elemeit is összehasonlítja.
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>
);
}Saját összehasonlítás
Második argumentumként bármilyen (left, right) => boolean függvény megfelel. Akkor használja, ha a shallow nem elég, például egy lista id szerinti összehasonlításához.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Változások összefogása batch-csel
Minden set azonnal értesíti a feliratkozókat. Ha egy művelet több store-t módosít, csomagolja batch-be: a memória azonnal frissül, a feliratkozók pedig a callback után egyszer futnak le.
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.
}Feliratkozás a Reacten kívül
A subscribeSelector csak akkor hívja meg Önt, ha a kiválasztott érték változik, ugyanazzal az opcionális összehasonlító függvénnyel.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Külső események bekötése
A restate második argumentuma lehet egy updater. Akkor fut, amikor az első komponens vagy feliratkozó elkezd figyelni, a takarítása pedig akkor, amikor az utolsó leáll, így a böngészőesemények, socketek vagy érzékelők csak addig vannak bekötve, amíg szükség van rájuk.
Kézi vezérléshez használja a start() és stop() metódust.
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);
};
});