Saltar al contenido principal

Mutaciones de datos

Usar nuestros endpoints de Create, Update y Delete con Controller.fetch() actualiza de forma reactiva todos los componentes apropiados de manera atómica (al mismo tiempo).

useController() da a los componentes acceso a este setState() global y potenciado.

import { useController } from '@data-client/react';
import { TodoResource, type Todo } from './TodoResource';

export default function TodoItem({ todo }: { todo: Todo }) {
  const ctrl = useController();
  const handleChange = e =>
    ctrl.fetch(
      TodoResource.partialUpdate,
      { id: todo.id },
      { completed: e.currentTarget.checked },
    );
  const handleDelete = () =>
    ctrl.fetch(TodoResource.delete, {
      id: todo.id,
    });
  return (
    <div className="listItem nogap">
      <label>
        <input
          type="checkbox"
          checked={todo.completed}
          onChange={handleChange}
        />
        {todo.completed ? <s>{todo.title}</s> : todo.title}
      </label>
      <CancelButton onClick={handleDelete} />
    </div>
  );
}
Resultado
Store▶

En lugar de desencadenar cascadas de invalidación o usar funciones de actualización escritas manualmente, Data Client actualiza de forma reactiva los componentes apropiados usando la respuesta del fetch.

Mutaciones optimistas basadas en el estado previo​

import { resource } from '@data-client/rest';
import { Post } from './Post';

export { Post };

export const PostResource = resource({
  path: '/posts/:id',
  searchParams: {} as { userId?: string | number } | undefined,
  schema: Post,
}).extend('vote', {
  path: '/posts/:id/vote',
  method: 'POST',
  body: undefined,
  schema: Post,
  getOptimisticResponse(snapshot, { id }) {
    const post = snapshot.get(Post, { id });
    if (!post) throw snapshot.abort;
    return {
      id,
      votes: post.votes + 1,
    };
  },
});
Resultado
Store▶

getOptimisticResponse es igual que setState con una función de actualización. Snapshot proporciona acceso con tipado seguro al valor previo del store, que usamos para devolver la respuesta esperada del fetch.

Reactive Data Client garantiza la integridad de los datos frente a cualquier posible fallo de red o condición de carrera, así que no te preocupes por fallos de red, por múltiples llamadas de mutación que editan los mismos datos, ni por otros problemas comunes de la programación asíncrona.

Seguimiento de la carga de una mutación​

useLoading() mejora las funciones asíncronas haciendo seguimiento de sus estados de carga y de error.

import { useLoading, useController } from '@data-client/react';
import { PostResource } from './PostResource';
import PostForm from './PostForm';

export default function PostCreate({ navigateToPost }) {
  const ctrl = useController();
  const [handleSubmit, loading, error] = useLoading(
    async data => {
      const post = await ctrl.fetch(PostResource.getList.push, data);
      navigateToPost(post.id);
    },
    [ctrl],
  );
  return (
    <PostForm onSubmit={handleSubmit} loading={loading} error={error} />
  );
}
Resultado
Store▶