Back to Trpc

useMutation()

www/docs/client/react/useMutation.md

11.16.02.1 KB
Original Source

:::note The hooks provided by @trpc/react-query are a thin wrapper around @tanstack/react-query. For in-depth information about options and usage patterns, refer to their docs on mutations. :::

Example

<details> <summary>Backend code</summary>
tsx
import { initTRPC } from '@trpc/server';
import { z } from 'zod';

export const t = initTRPC.create();

export const appRouter = t.router({
  // Create procedure at path 'login'
  // The syntax is identical to creating queries
  login: t.procedure
    // using zod schema to validate and infer input values
    .input(
      z.object({
        name: z.string(),
      }),
    )
    .mutation((opts) => {
      // Here some login stuff would happen
      return {
        user: {
          name: opts.input.name,
          role: 'ADMIN' as const,
        },
      };
    }),
});

export type AppRouter = typeof appRouter;
</details>
tsx
// @filename: server.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';
const t = initTRPC.create();
const appRouter = t.router({
  login: t.procedure
    .input(z.object({ name: z.string() }))
    .mutation((opts) => {
      return { user: { name: opts.input.name, role: 'ADMIN' as const } };
    }),
});
export type AppRouter = typeof appRouter;

// @filename: utils/trpc.tsx
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '../server';
export const trpc = createTRPCReact<AppRouter>();

// @filename: components/MyComponent.tsx
import React from 'react';
// ---cut---
import { trpc } from '../utils/trpc';

export function MyComponent() {
  const mutation = trpc.login.useMutation();

  const handleLogin = () => {
    const name = 'John Doe';

    mutation.mutate({ name });
  };

  return (
    <div>
      <h1>Login Form</h1>
      <button onClick={handleLogin} disabled={mutation.isPending}>
        Login
      </button>

      {mutation.error && <p>Something went wrong! {mutation.error.message}</p>}
    </div>
  );
}