Grow your SaaS organically with Programmatic SEO.
Try for free →SaaS apps constantly contact the backend APIs to create, read, update, and delete data - CRUD. Using libraries like Redux to do state management with their complex boilerplate of Actions, Reducers, and Middlewares will get complicated as the size of the application grows. Redux Query keeps it simple.
I'm using React Query in my SaaS app, launchman.io to fetch a list of sites data. When a new site is created, a POST request is made. The list of sites is then re-fetched, and a toast is displayed when the request is successful.
Using React Query in SaaS app In this post, you will learn how to:
npm i @tanstack/react-query
Let's start nice and easy with a simple GET request.
We can get the list of sites owned by a user with a specified email
by sending out a GET request using Axios. React Query has a hook called useQuery
that takes in:
import axios from "axios";
import { useQuery, useQueryClient } from "@tanstack/react-query";
const fetchSites = async (email: string) => {
const response = await axios.get(`api/users/${email}`);
return response;
};
const useSites = (email: string) => {
return useQuery(["sites", email], () => fetchSites(email));
};
export { useSites };
We can now consume these hooks in a React component by importing useSites
and use it like so:
import { FunctionComponent } from "react";
import { useSites } from "../../hooks/api";
interface AppProps {}
const App: FunctionComponent<AppProps> = () => {
const { data, isLoading, isFetching } = useSites("sukh@email.com");
if (isLoading) {
return <p>Loading...</p>;
}
return <div>{JSON.stringify(data)}</div>;
};
export default App;
Notice that you get the status of the query for free with React Query. You can use this to show Loading states in the UI.
Now that we can fetch our data. Let's take a look at how we can create new data.
When creating a new resource, you should be making a POST request with Axios with the body containing the data.
React Query has another hook specifically for mutations called useMutation
. It takes just the function to call when the hook is used. This would be your Axios request.
When the new data is created, your previously fetched data will be stale. This is where useMutation
lets you specify a onSuccess
function that runs right after the query is successful. Using queryClient
the key you specified in useSites
hook, the data will automatically be re-fetched.
import axios from "axios";
import { useMutation, useQueryClient } from "@tanstack/react-query";
const useCreateSite = () => {
const queryClient = useQueryClient();
return useMutation((data: any) => axios.post("/api/sites", data), {
onSuccess: () => {
queryClient.invalidateQueries(["sites"]);
// good place to throw a toast/notification to let the user know
},
});
};
export { useCreateSite };
In your React component, you can trigger a mutation like so:
import { FunctionComponent } from "react";
import { useSites } from "../../hooks/api";
interface AppProps {}
const App: FunctionComponent<AppProps> = () => {
const { mutate: createSiteMutation } = useCreateSite();
return (
<div>
<button
onClick={() => {
createSiteMutation({
data,
});
}}
></button>
</div>
);
};
export default App;
Updating data is largely the same as Creating in the last section. You can useMutation
to specify a PATCH
Axios request and pass in the data to update. Once successful, invalidate the query using the query key you defined in the useSites
.
const useUpdateSite = () => {
const queryClient = useQueryClient();
return useMutation(
({ subdomain, ...data }: any) =>
axios.patch(`/api/sites/${subdomain}`, data),
{
onSuccess: () => {
queryClient.invalidateQueries(["sites"]);
},
}
);
};
export { useUpdateSite };
To use in React component:
import { FunctionComponent } from "react";
import { useUpdateSite } from "../../hooks/api";
interface AppProps {}
const App: FunctionComponent<AppProps> = () => {
const { mutate: updateSiteMutation } = useUpdateSite();
return (
<div>
<button
onClick={() => {
useUpdateSite({
data,
subdomain,
});
}}
></button>
</div>
);
};
export default App;
When a user creates new data, it's good UX practice to show a notification on success. We can do this very quickly with React Query. I'm using the Toast component from Chakra UI but you can use another library like React Toastify as well.
import axios from "axios";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useToast } from "@chakra-ui/toast";
const useCreateSite = () => {
const queryClient = useQueryClient();
const toast = useToast();
return useMutation((data: any) => axios.post("/api/sites", data), {
onSuccess: () => {
queryClient.invalidateQueries(["sites"]);
toast({
title: "Created site.",
description: "We've created a new site for you.",
status: "success",
duration: 9000,
isClosable: true,
});
},
});
};
export { useCreateSite };
I'm building a new SaaS to automate content marketing for your SaaS
Tools for SaaS Devs