restate / v1.0.0

Iscriviti solo a ciò che ti serve

Scegli da quale parte di uno store dipende ogni componente, confronta oggetti con shallow, raggruppa le modifiche con batch e collega eventi esterni.

In questa paginaPassa un selectorProvaloSeleziona più campi con shallowScrivi il tuo confrontoRaggruppa le modifiche con batchIscriviti fuori da ReactCollega eventi esterni

Passa un selector

Chiama l’hook con una funzione che sceglie ciò che serve al componente. Dopo ogni modifica restate esegue il selector e confronta il risultato con il precedente usando Object.is. Se sono uguali, il componente non si renderizza.

Il biglietto cambia. ItemCount si renderizza?

No. Il suo selector restituisce ancora lo stesso numero di articoli, quindi la selezione è uguale e a React non viene chiesto di renderizzarlo.

JavaScript / JSX
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>;
}

Provalo

Cambia i campi e guarda i contatori dei render. Disattiva shallow per vedere un selector che restituisce ogni volta un oggetto nuovo.

Preparazione dell’esempio…

Seleziona più campi con shallow

Un selector che costruisce un oggetto ne restituisce ogni volta uno nuovo, quindi Object.is vede sempre un cambiamento. Passa shallow come secondo argomento: confronta i campi propri dell’oggetto a un livello di profondità.

shallow confronta a un livello anche gli elementi di array, Map e Set.

JavaScript / JSX
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>
  );
}

Scrivi il tuo confronto

Qualsiasi funzione (left, right) => boolean va bene come secondo argomento. Usala quando shallow non basta, per esempio per confrontare una lista per id.

JavaScript / JSX
const ids = useCart(
  (cart) => cart.items.map((item) => item.id),
  (left, right) => left.length === right.length && left.every((id, index) => id === right[index]),
);

Raggruppa le modifiche con batch

Ogni set notifica subito gli iscritti. Quando un’azione cambia più store, avvolgila in batch: la memoria si aggiorna subito e gli iscritti vengono eseguiti una volta dopo il callback.

JavaScript / JSX
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.
}

Iscriviti fuori da React

subscribeSelector ti chiama solo quando cambia il valore selezionato, con la stessa funzione di confronto opzionale.

JavaScript / JSX
const stop = useCart.subscribeSelector(
  (cart) => cart.items.length,
  (count, previous) => analytics.track('cart-size', { count, previous }),
);

Collega eventi esterni

Il secondo argomento di restate può essere un updater. Parte quando il primo componente o iscritto inizia ad ascoltare, e la sua pulizia viene eseguita quando l’ultimo smette, così eventi del browser, socket o sensori restano collegati solo finché servono.

Usa start() e stop() per controllarlo a mano.

JavaScript / JSX
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);
  };
});

Cerca nella documentazione

Cerca nei titoli, nelle descrizioni e nel testo di tutte le guide.