restate / v1.0.0
Abonner bare på det du trenger
Velg hvilken del av en store hver komponent avhenger av, sammenlign objekter med shallow, grupper endringer med batch og koble til eksterne hendelser.
På denne siden
Send en selectorPrøv detVelg flere felt med shallowSkriv din egen sammenligningGrupper endringer med batchAbonner utenfor ReactKoble til eksterne hendelserSend en selector
Kall hooken med en funksjon som velger det komponenten trenger. Etter hver endring kjører restate selectoren og sammenligner resultatet med det forrige med Object.is. Er de like, renderes ikke komponenten.
Kortet endres. Renderes ItemCount?
Nei. Dens selector returnerer fortsatt det samme antallet varer, så utvalget er likt, og React blir ikke bedt om å rendere den.
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øv det
Endre feltene og følg med på renderingstellerne. Slå av shallow for å se en selector som returnerer et nytt objekt hver gang.
Forbereder eksempelet …
Velg flere felt med shallow
En selector som bygger et objekt, returnerer et nytt hver gang, så Object.is ser alltid en endring. Send shallow som andre argument: den sammenligner objektets egne felt ett nivå dypt.
shallow sammenligner også elementer i arrays, Map og Set ett nivå dypt.
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>
);
}Skriv din egen sammenligning
Enhver funksjon (left, right) => boolean kan brukes som andre argument. Bruk en når shallow ikke er nok, for eksempel for å sammenligne en liste etter id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Grupper endringer med batch
Hvert set varsler abonnentene med en gang. Når én handling endrer flere stores, pakker du den inn i batch: minnet oppdateres med en gang, og abonnentene kjøres én gang etter callbacken.
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.
}Abonner utenfor React
subscribeSelector kaller deg bare når den valgte verdien endres, med den samme valgfrie sammenligningsfunksjonen.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Koble til eksterne hendelser
Det andre argumentet til restate kan være en updater. Den starter når den første komponenten eller abonnenten begynner å lytte, og oppryddingen kjøres når den siste slutter, så nettleserhendelser, sockets eller sensorer bare er koblet til så lenge de trengs.
Bruk start() og stop() for å styre den manuelt.
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);
};
});