Skip to content
/ tsrq Public

Generate type-safe React Query hooks without boilerplate

License

Notifications You must be signed in to change notification settings

arn4v/tsrq

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tsrq

Introduction

When using React Query, for the same query, you can either copy paste the code into different components or abstract it into a custom hook. The first one is just bad practice and the second method become unmanageable very quickly as your app (and # of endpoints) grows.

With TSRQ, you only define you write code for your queries and mutations once and reuse them wherever you want.

Install

npm:

npm i -S tsrq react-query

yarn:

yarn add tsrq react-query

Quick Start Example:

import {
	createQueryBuilder,
	createUseQuery,
	createUseMutation,
} from "typed-query";

interface ITodo {
	id: string;
	title: string;
}

const builder = createQueryBuilder()
	.query("todos", async () => {
		return await fetch("/todos").then(res => res.json() as Array<ITodo>);
	})
	.query("byId", async (id: string) => {
		return await fetch(`/todos/${id}`).then(res => res.json() as ITodo);
	})
	.mutation("updateTodo", async ({ id, title }: ITodo) => {
		return await fetch(`/todos/${id}`, {
			method: "PATCH",
			body: JSON.stringify({ title }),
		}).then(res => res.json() as ITodo);
	});

const useQuery = createUseQuery(builder);
const useMutation = createUseMutation(builder);

export default function TodosList() {
	// If query requires no parameters then you must
	// provide an empty array
	const { data } = useQuery("todos", []);

	return (
		<ul>
			{data?.map(item => (
				<li key={item.id}>{item.title}</li>
			))}
		</ul>
	);
}

export default function TodoPage({ id }: { id: string }) {
	// Provide query parameters as array in second arg
	const { data } = useQuery("byId", [id]);
	const { mutate } = useMutation("updateTodo");

	return <div>{data?.title}</div>;
}

API Reference

  • createQueryBuilder

Create instance:

import { createQueryBuilder } from "tsrq";

const builder = createQueryBuilder();

Add Query to Instance:

import { createQueryBuilder } from "tsrq";

const builder = createQueryBuilder().query("todos", () => {
	return fetch("/todos").then(res => res.json());
});

Add Mutation to Instance:

import { createQueryBuilder } from "tsrq";

const builder = createQueryBuilder().mutation("add", (title: string) => {
	return fetch("/todos", {
		method: "POST",
		body: JSON.stringify({
			title,
		}),
	});
});
  • createUseQuery
import { createQueryBuilder, createUseQuery } from "tsrq";

// Builder Code
const builder = createQueryBuilder();
// ...End Builder Code

export const useQuery = createUseQuery(builder);

Usage:

When query requires params:

import * as React from "react";
import { useQuery } from "./tsrq.config";

const TodoPage = ({ id }: { id: string }) => {
	const { data, isLoading } = useQuery("byId", [id]);

	if (isLoading) return null;

	return <div>{/** JSX */}</div>;
};

When query doesn't require params:

import * as React from "react";
import { useQuery } from "./tsrq.config";

export default function TodosList() {
	// If query requires no parameters then you must
	// provide an empty array
	const { data } = useQuery("todos", []);

	return (
		<ul>
			{data?.map(item => (
				<li key={item.id}>{item.title}</li>
			))}
		</ul>
	);
}
  • createUseMutation
import { createQueryBuilder, createUseMutation } from "tsrq";

// Builder Code
const builder = createQueryBuilder();
// ...End Builder Code

export const useMutation = createUseMutation(builder);

Usage:

import * as React from "react";
import { useMutation } from "./tsrq.config";

const CreateTodoPage = () => {
	const [title, setTitle] = React.useState("");
	const { mutate } = useMutation("add");

	const addTodo = () => {
		mutate(title);
	};
	return <div>{/** JSX */}</div>;
};

Credits

  • Alex Johansson (@katt) for tRPC. This library is heavily inspired by trpc. TSRQ QueryBuilder implementation is similar to TRPC's Router implementation.