Pular para o conteúdo principal

Data Client

Mutações reativas

Renderize dados com useSuspense(). Depois faça mutações com Controller.fetch().

Isso atualiza todos os usos de forma atômica e imediata sem nenhuma requisição adicional. O Reactive Data Client garante automaticamente a consistência e integridade global dos dados, mesmo nas condições de corrida mais difíceis.

Editor em tempo real
import { UserResource } from './resources';

export default function ProfileEdit({ id }: { id: number }) {
  const user = useSuspense(UserResource.get, { id });

  const controller = useController();
  const handleChange = ({ currentTarget: { value: name } }) =>
    controller.fetch(UserResource.partialUpdate, { id }, { name });

  return (
    <TextInput
      label="Name"
      value={user.name}
      onChange={handleChange}
    />
  );
}
Resultado
Store▶
Editor em tempo real
import { UserResource } from './resources';

export default function ProfileEdit({ id }: { id: number }) {
  const { user } = useSuspense(UserResource.get, { id });

  const controller = useController();
  const handleChange = ({ currentTarget: { value: name } }) =>
    controller.fetch(UserResource.update, { id, name });

  return (
    <TextInput
      label="Name"
      value={user.name}
      onChange={handleChange}
    />
  );
}
Resultado
Store▶

Dados estruturados

A consistência dos dados, o desempenho e a segurança de tipos escalam mesmo quando seus dados ficam mais complexos.

As criações e exclusões atualizam de forma reativa as listas corretas, mesmo quando essas listas estão aninhadas dentro de outros objetos.

Modele até os dados mais complexos com suporte polimórfico e a objetos e mapas sem limites.

Editor em tempo real
import { TodoResource } from './resources';

export default function NewTodo({ userId }: { userId: number }) {
  const controller = useController();
  const handleKeyDown = async e => {
    if (e.key === 'Enter') {
      controller.fetch(TodoResource.getList.push, {
        userId,
        title: e.currentTarget.value,
      });
      e.currentTarget.value = '';
    }
  };
  return (
    <div className="listItem nogap">
      <label>
        <input type="checkbox" name="new" checked={false} disabled />
        <TextInput size="small" onKeyDown={handleKeyDown} />
      </label>
      <CancelButton />
    </div>
  );
}
Resultado
Store▶

Atualizações ao vivo

Mantenha as mudanças remotas sincronizadas com useLive().

Polling, SSE e Websocket ou suporte a um protocolo próprio com middlewares

Editor em tempo real
import { getTicker } from './resources';

export default function AssetPrice({ symbol }: { symbol: string }) {
  const productId = `${symbol}-USD`;
  const ticker = useLive(getTicker, { productId });
  return (
    <tr>
      <th>{symbol}</th>
      <td align="right">
        <NumberFlow
          value={ticker.price}
          format={{ style: 'currency', currency: 'USD' }}
        />
      </td>
    </tr>
  );
}
Resultado
Store▶

Integridade dos dados

Tipos inferidos fortes; uma única fonte de verdade, referencialmente estável, garante a consistência; as invariantes assíncronas facilitam evitar condições de corrida

Desempenho

Navegação 24x mais rápida que React puro, 10x mais rápida que TanStack Query e SWR. Mutações 92x mais rápidas que TanStack Query, SWR e React puro.

Composição em vez de configuração

Declare o que você precisa onde você precisa. Compartilhe definições de dados entre plataformas, componentes, protocolos e comportamentos.

Adoção incremental

Comece rápido com uma definição de dados de uma linha e um vínculo de dados de uma linha. Depois adicione TypeScript, cache normalizado com Schemas, atualizações otimistas e mais.

Uma aplicação completa

Um navegador de issues e pull requests do GitHub sobre a API do GitHub ao vivo, criado com resources REST e Suspense.

Explore o exemplo github-app

More Demos