restate / v1.0.0
Abonnér kun på det, du har brug for
Vælg, hvilken del af en store hver komponent afhænger af, sammenlign objekter med shallow, saml ændringer med batch, og forbind eksterne events.
På denne side
Giv en selectorPrøv detVælg flere felter med shallowSkriv din egen sammenligningSaml ændringer med batchAbonnér uden for ReactForbind eksterne eventsGiv en selector
Kald hooken med en funktion, der vælger det, komponenten har brug for. Efter hver ændring kører restate din selector og sammenligner resultatet med det forrige med Object.is. Er de ens, renderes komponenten ikke.
Kortet ændrer sig. Renderes ItemCount?
Nej. Dens selector returnerer stadig det samme antal varer, så udvalget er ens, og React bliver ikke bedt om at 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
Ændr felterne, og hold øje med renderingstællerne. Slå shallow fra for at se en selector, der returnerer et nyt objekt hver gang.
Forbereder eksemplet…
Vælg flere felter med shallow
En selector, der bygger et objekt, returnerer et nyt hver gang, så Object.is ser altid en ændring. Giv shallow som andet argument: den sammenligner objektets egne felter ét niveau dybt.
shallow sammenligner også elementer i arrays, Map og Set ét niveau dybt.
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 funktion (left, right) => boolean kan bruges som andet argument. Brug en, når shallow ikke er nok, for eksempel til at sammenligne en liste efter id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Saml ændringer med batch
Hvert set giver straks abonnenter besked. Når én handling ændrer flere stores, så pak den ind i batch: hukommelsen opdateres med det samme, og abonnenterne kører én gang efter 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.
}Abonnér uden for React
subscribeSelector kalder dig kun, når den valgte værdi ændrer sig, med den samme valgfrie sammenligningsfunktion.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Forbind eksterne events
Det andet argument til restate kan være en updater. Den starter, når den første komponent eller abonnent begynder at lytte, og dens oprydning kører, når den sidste stopper, så browser-events, sockets eller sensorer kun er forbundet, så længe de er nødvendige.
Brug start() og stop() til at 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);
};
});