restate / v1.0.0

Ne s’abonner qu’au nécessaire

Choisissez la partie d’un store dont dépend chaque composant, comparez des objets avec shallow, regroupez les changements avec batch et branchez des événements externes.

Sur cette pagePasser un selectorEssayerSélectionner plusieurs champs avec shallowÉcrire votre propre comparaisonRegrouper les changements avec batchS’abonner en dehors de ReactBrancher des événements externes

Passer un selector

Appelez le hook avec une fonction qui choisit ce dont le composant a besoin. Après chaque changement, restate exécute le selector et compare le résultat au précédent avec Object.is. S’ils sont égaux, le composant ne se rend pas.

Le message change. ItemCount se rend-il ?

Non. Son selector renvoie toujours le même nombre d’articles : la sélection est égale, donc React n’est pas sollicité pour le rendre.

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>;
}

Essayer

Modifiez des champs et observez les compteurs de rendus. Désactivez shallow pour voir un selector qui renvoie un nouvel objet à chaque fois.

Préparation de l’exemple…

Sélectionner plusieurs champs avec shallow

Un selector qui construit un objet en renvoie un nouveau à chaque fois, donc Object.is voit toujours un changement. Passez shallow en second argument : il compare les champs propres de l’objet sur un niveau.

shallow compare aussi les entrées des tableaux, des Map et des Set sur un niveau.

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>
  );
}

Écrire votre propre comparaison

N’importe quelle fonction (left, right) => boolean convient comme second argument. Utilisez-la quand shallow ne suffit pas, par exemple pour comparer une liste par ids.

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]),
);

Regrouper les changements avec batch

Chaque set notifie les abonnés immédiatement. Quand une action modifie plusieurs stores, enveloppez-la dans batch : la mémoire se met à jour tout de suite, et les abonnés s’exécutent une fois après le 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.
}

S’abonner en dehors de React

subscribeSelector ne vous appelle que lorsque la valeur sélectionnée change, avec la même fonction de comparaison facultative.

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

Brancher des événements externes

Le second argument de restate peut être un updater. Il démarre quand le premier composant ou abonné commence à écouter, et son nettoyage s’exécute quand le dernier s’arrête : les événements du navigateur, les sockets ou les capteurs ne sont connectés que lorsque c’est nécessaire.

Utilisez start() et stop() pour le piloter à la main.

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);
  };
});

Rechercher dans la documentation

Recherche dans les titres, les descriptions et le texte de tous les guides.