Skip to content
main
Switch branches/tags
Code

React Query Helper

npm version npm bundle size npm bundle size Test codecov GitHub

A helper library to help you use React Query more easily and consistently.

Features

  • Write query key once, use everywhere. you don't have to remember something's query key; the query key will be generated with your baseQueryKey and arguments of queryFn that you were called as defined
  • Written in TypeScript. you can infer your query result type/interface.

Why?

I've been using React Query for 2-3 years. In most situations, I used to make a custom hook and manage query keys as constant strings. but it was quite tiring.

Sometimes, It makes me sad when the query data type that I inferred manually is not equal with the actual query data type. for example:

// Set query's data.
queryClient.setQueryData([queryKeys.product.all], [{}] as IProductList);

// It is unknown type:
queryClient.getQueryData([queryKeys.product.all]);

// Okay, we know we can use generic type but we can also make a mistake.
// These mistakes are quite hard to find.
queryClient.getQueryData<IProduct>([queryKeys.product.all]);
queryClient.getQueryData<IProductList>([queryKeys.category.all]);

Essentially, Making a custom hook using useQuery or managing Query Keys as constants strings are not guaranteed your query result type. so you have to infer types manually like queryClient.getQueryData<IProductList> or you'll get unknown type as result.

Installation

NOTE: This libary depends on React Query as a peer dependency.

$ yarn add react-query react-query-helper

# or npm:
$ npm install react-query react-query-helper

Usage

Call makeQueryHelper function to create query helper. Examples:

import { makeQueryHelper } from 'react-query-helper';
import { queryClient } from '../queryClient';
import type { User } from '../types';

export const getUserById = makeQueryHelper({
  queryClient,
  baseQueryKey: ['user'],
  // NOTE: You can access QueryFunctionContext in your function scope.
  queryFn: (context) => (id: number) => {
    return fetch(`https://jsonplaceholder.typicode.com/users/${id}/`).then(
      (response) => response.json() as Promise<User>
    );
  },
});

Now you can use type-safe useQuery and get or set query data type-safety.

import { getUserById } from '../remotes/getUserById';

const UserInfo: FC = () => {
  const { data } = getUserById.useQuery(1);

  return <p>name: {data?.name}</p>;
};

const UserUpdater: FC = () => {
  const handleClick = () => {
    const user = getUserById.getQueryData(1);

    if (user) {
      getUserById.setQueryData(1, {
        ...user,
        name: 'John Doe',
      });
    }
  };

  return <button onClick={handleClick}>Update name</button>;
};

Examples

More examples will be added by library progress.

Contribution

There's no contribute guide. I will write soon. currently, Please consider sharing feedback or reporting an issue.

License

MIT (See the LICENSE file)