React Query is often described as the missing data-fetching library for React, but in more technical terms, it makes fetching, caching, synchronizing and updating server state in your React applications a breeze.
Examples
import * as React from 'react';
import { FaCheckCircle, FaPlusCircle, FaMinusCircle, FaBook, FaTimesCircle } from 'react-icons/fa';
import Tooltip from '@reach/tooltip';
import { useMutation, queryCache, useQuery } from 'react-query';
import { client } from 'utils/api-client';
import * as colors from 'styles/colors';
import { CircleButton, Spinner } from './lib';
function StatusButtons({ user, book }) {
const { data: listItems } = useQuery({
queryKey: 'list-items',
queryFn: () => client(`list-items`, { token: user.token }).then((data) => data.listItems),
});
const listItem = listItems?.find((li) => li.bookId === book.id) ?? null;
const [remove] = useMutation(({ id }) => client(`list-items/${id}`, { method: 'DELETE', token: user.token }), { onSettled: () => queryCache.invalidateQueries('list-items') });
const [create] = useMutation(({ bookId }) => client(`list-items`, { data: { bookId }, token: user.token }), { onSettled: () => queryCache.invalidateQueries('list-items') });
const [update] = useMutation(
(updates) =>
client(`list-items/${updates.id}`, {
method: 'PUT',
data: updates,
token: user.token,
}),
{ onSettled: () => queryCache.invalidateQueries('list-items') },
);
return (
<React.Fragment>
{listItem ? Boolean(listItem.finishDate) ? <TooltipButton label='Unmark as read' highlight={colors.yellow} onClick={() => update({ id: listItem.id, finishDate: null })} icon={<FaBook />} /> : <TooltipButton label='Mark as read' highlight={colors.green} onClick={() => update({ id: listItem.id, finishDate: Date.now() })} icon={<FaCheckCircle />} /> : null}
{listItem ? <TooltipButton label='Remove from list' highlight={colors.danger} onClick={() => remove({ id: listItem.id })} icon={<FaMinusCircle />} /> : <TooltipButton label='Add to list' highlight={colors.indigo} onClick={() => create({ bookId: book.id })} icon={<FaPlusCircle />} />}
</React.Fragment>
);
}
export { StatusButtons };