restate / v1.0.0
Odoberajte len to, čo potrebujete
Zvoľte, od ktorej časti store každý komponent závisí, porovnávajte objekty cez shallow, zoskupujte zmeny cez batch a pripájajte vonkajšie udalosti.
Na tejto stránke
Odovzdajte selectorVyskúšajteVýber viacerých polí cez shallowVlastné porovnanieZoskupenie zmien cez batchOdber mimo ReactPripojenie vonkajších udalostíOdovzdajte selector
Zavolajte hook s funkciou, ktorá vyberie, čo komponent potrebuje. Po každej zmene restate spustí selector a porovná výsledok s predchádzajúcim cez Object.is. Ak sú rovnaké, komponent sa neprekreslí.
Kartička sa zmení. Prekreslí sa ItemCount?
Nie. Jeho selector stále vracia rovnaký počet položiek, takže výber je rovnaký a React nemusí nič prekresľovať.
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>;
}Vyskúšajte
Meňte polia a sledujte počítadlá renderov. Vypnite shallow a uvidíte selector, ktorý zakaždým vracia nový objekt.
Príprava príkladu…
Výber viacerých polí cez shallow
Keď selector skladá objekt, vracia zakaždým nový, takže Object.is vždy vidí zmenu. Odovzdajte shallow ako druhý argument: porovná vlastné polia objektu do hĺbky jednej úrovne.
shallow porovnáva do jednej úrovne aj prvky polí, Map a 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>
);
}Vlastné porovnanie
Ako druhý argument poslúži akákoľvek funkcia (left, right) => boolean. Použite ju, keď shallow nestačí, napríklad na porovnanie zoznamu podľa id.
const ids = useCart(
(cart) => cart.items.map((item) => item.id),
(left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);Zoskupenie zmien cez batch
Každé set hneď upozorní odberateľov. Keď jedna akcia mení viac store, obaľte ju do batch: pamäť sa aktualizuje hneď a odberatelia sa spustia raz po callbacku.
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.
}Odber mimo React
subscribeSelector vás zavolá, len keď sa vybraná hodnota zmení, s rovnakou voliteľnou porovnávacou funkciou.
const stop = useCart.subscribeSelector(
(cart) => cart.items.length,
(count, previous) => analytics.track('cart-size', { count, previous }),
);Pripojenie vonkajších udalostí
Druhým argumentom restate môže byť updater. Spustí sa, keď začne počúvať prvý komponent alebo odberateľ, a jeho upratanie prebehne, keď prestane posledný, takže udalosti prehliadača, sockety alebo senzory sú pripojené len dovtedy, kým sú potrebné.
Na ručné ovládanie použite start() a 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);
};
});