react query in typescript

To use react-query with typescript, you need to first install the library and its types:

index.ts
npm install react-query
npm install @types/react-query
55 chars
3 lines

You can then use react-query's hooks in your functional components:

index.ts
import { useQuery } from 'react-query';
import { User } from 'my-app/types';

function MyComponent() {
  const { isLoading, data, error } = useQuery<User>('users', () =>
    fetch('/api/users').then(res => res.json())
  );

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  return (
    <ul>
      {data.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
464 chars
25 lines

In the example above, useQuery is used to fetch a list of User objects from the /api/users endpoint. The data and error states are destructured from the hook's result for rendering purposes. The generic type argument 'users' is used as a key for caching purposes.

You can also use react-query's useMutation hook for making mutations to your API and updating the cache accordingly:

index.ts
import { useMutation, useQueryClient } from 'react-query';
import { User } from 'my-app/types';

function CreateUserForm() {
  const queryClient = useQueryClient();

  const { mutate, isLoading } = useMutation<User, Error, User>(
    (user: User) =>
      fetch('/api/users', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(user),
      }).then(res => res.json()),
    {
      onSuccess: (data) => {
        queryClient.setQueryData<User[]>('users', (old) =>
          old ? [...old, data] : [data]
        );
      },
    }
  );

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    const form = event.target as HTMLFormElement;
    const formData = new FormData(form);

    mutate(Object.fromEntries(formData.entries()) as User);
  };

  if (isLoading) {
    return <div>Creating user...</div>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="name" required />
      <input type="email" name="email" required />
      <button type="submit">Create user</button>
    </form>
  );
}
1130 chars
44 lines

In the example above, useMutation is used to create a new User object by making a POST request to the /api/users endpoint. The onSuccess option is used to update the cache by appending the new user to the existing list of users stored under the 'users' key. The useQueryClient hook is used to obtain access to the query client used by react-query.

Note that you need to provide your custom types for User and Error wherever you use them. In the examples above, I assumed they are defined in my-app/types.

gistlibby LogSnag