restate / v1.0.0

Assine só o que você precisa

Escolha de qual parte de um store cada componente depende, compare objetos com shallow, agrupe mudanças com batch e conecte eventos externos.

Nesta páginaPasse um selectorExperimenteSelecione vários campos com shallowEscreva sua própria comparaçãoAgrupe mudanças com batchAssine fora do ReactConecte eventos externos

Passe um selector

Chame o hook com uma função que escolhe o que o componente precisa. Depois de cada mudança, o restate executa o selector e compara o resultado com o anterior usando Object.is. Se forem iguais, o componente não renderiza.

A mensagem muda. O ItemCount renderiza?

Não. O selector dele continua retornando o mesmo número de itens, então a seleção é igual e o React não é chamado para renderizá-lo.

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

Experimente

Mude os campos e acompanhe os contadores de renders. Desligue shallow para ver um selector que retorna um objeto novo toda vez.

Preparando o exemplo…

Selecione vários campos com shallow

Um selector que monta um objeto retorna um objeto novo toda vez, então Object.is sempre vê uma mudança. Passe shallow como segundo argumento: ele compara os campos próprios do objeto em um nível.

shallow também compara itens de arrays, Map e Set em um nível.

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

Escreva sua própria comparação

Qualquer função (left, right) => boolean serve como segundo argumento. Use quando shallow não bastar, por exemplo para comparar uma lista pelos 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]),
);

Agrupe mudanças com batch

Cada set notifica os assinantes na hora. Quando uma ação muda vários stores, envolva-a em batch: a memória é atualizada imediatamente e os assinantes rodam uma vez depois do 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.
}

Assine fora do React

subscribeSelector só chama você quando o valor selecionado muda, com a mesma função de comparação opcional.

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

Conecte eventos externos

O segundo argumento de restate pode ser um updater. Ele começa quando o primeiro componente ou assinante começa a escutar, e a limpeza roda quando o último para, então eventos do navegador, sockets ou sensores só ficam conectados enquanto são necessários.

Use start() e stop() para controlá-lo manualmente.

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

Pesquisar na documentação

Pesquisa em títulos, descrições e texto de todos os guias.