restate / v1.0.0
Pretplatite se samo na ono što trebate
Odaberite o kojem dijelu storea ovisi svaka komponenta, uspoređujte objekte preko shallow, grupirajte promjene preko batch i povežite vanjske događaje.
Na ovoj stranici
Predajte selectorIsprobajteOdabir više polja preko shallowVlastita usporedbaGrupiranje promjena preko batchPretplata izvan ReactaPovezivanje vanjskih događajaPredajte selector
Pozovite hook s funkcijom koja odabire ono što komponenta treba. Nakon svake promjene restate pokreće selector i uspoređuje rezultat s prethodnim preko Object.is. Ako su jednaki, komponenta se ne renderira.
Čestitka se mijenja. Renderira li se ItemCount?
Ne. Njegov selector i dalje vraća isti broj artikala, pa je odabir jednak i od Reacta se ne traži renderiranje.
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>;
}Isprobajte
Mijenjajte polja i pratite brojače renderiranja. Isključite shallow da biste vidjeli selector koji svaki put vraća novi objekt.
Priprema primjera…
Odabir više polja preko shallow
Kad selector slaže objekt, svaki put vraća novi, pa Object.is uvijek vidi promjenu. Predajte shallow kao drugi argument: uspoređuje vlastita polja objekta na dubini jedne razine.
shallow na jednoj razini uspoređuje i elemente nizova, Map i 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>
);
}Vlastita usporedba
Kao drugi argument poslužit će bilo koja funkcija (left, right) => boolean. Koristite je kad shallow nije dovoljan, primjerice za usporedbu popisa po id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Grupiranje promjena preko batch
Svaki set odmah obavještava pretplatnike. Kad jedna radnja mijenja više storeova, omotajte je u batch: memorija se odmah ažurira, a pretplatnici se pokreću jednom nakon callbacka.
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.
}Pretplata izvan Reacta
subscribeSelector vas poziva samo kad se odabrana vrijednost promijeni, s istom neobaveznom funkcijom usporedbe.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Povezivanje vanjskih događaja
Drugi argument restate može biti updater. Pokreće se kad prva komponenta ili pretplatnik počne slušati, a njegovo čišćenje izvodi se kad prestane posljednji, pa su događaji preglednika, socketi ili senzori povezani samo dok su potrebni.
Za ručno upravljanje koristite start() i 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);
};
});