restate / v1.0.0

Abonați-vă doar la ce vă trebuie

Alegeți de ce parte a store-ului depinde fiecare componentă, comparați obiecte cu shallow, grupați modificările cu batch și conectați evenimente externe.

Pe această paginăDați un selectorÎncercațiSelectarea mai multor câmpuri cu shallowComparație proprieGruparea modificărilor cu batchAbonare în afara ReactConectarea evenimentelor externe

Dați un selector

Apelați hook-ul cu o funcție care alege ce îi trebuie componentei. După fiecare schimbare, restate rulează selectorul și compară rezultatul cu cel anterior prin Object.is. Dacă sunt egale, componenta nu se randează.

Cardul se schimbă. Se randează ItemCount?

Nu. Funcția selector a lui returnează în continuare același număr de produse, deci selecția e egală și React nu e rugat să randeze.

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

Încercați

Schimbați câmpuri și urmăriți contoarele de randare. Dezactivați shallow ca să vedeți un selector care returnează un obiect nou de fiecare dată.

Se pregătește exemplul…

Selectarea mai multor câmpuri cu shallow

Când un selector construiește un obiect, returnează unul nou de fiecare dată, așa că Object.is vede mereu o schimbare. Dați shallow ca al doilea argument: compară câmpurile proprii ale obiectului la un nivel de adâncime.

shallow compară și elementele tablourilor, Map-urilor și Set-urilor la un nivel de adâncime.

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

Comparație proprie

Orice funcție (left, right) => boolean merge ca al doilea argument. Folosiți-o când shallow nu ajunge, de exemplu pentru a compara o listă după 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]),
);

Gruparea modificărilor cu batch

Fiecare set notifică imediat abonații. Când o acțiune schimbă mai multe store-uri, înfășurați-o în batch: memoria se actualizează imediat, iar abonații rulează o dată după 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.
}

Abonare în afara React

subscribeSelector vă apelează doar când se schimbă valoarea selectată, cu aceeași funcție opțională de comparare.

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

Conectarea evenimentelor externe

Al doilea argument al lui restate poate fi un updater. Rulează când prima componentă sau primul abonat începe să asculte, iar curățarea lui rulează când se oprește ultimul, așa că evenimentele browserului, socket-urile sau senzorii sunt conectate doar cât e nevoie.

Pentru control manual folosiți start() și stop().

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

Căutați în documentație

Căutați în titlurile, descrierile și conținutul tuturor ghidurilor.