Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

deve-sh/useFetch

Repository files navigation

useFetch - A Simple hook-based fetcher and caching implementation

Read the blog post about building this library: https://blog.devesh.tech/post/creating-our-own-swr

Features

  • Reactivity Baked In
  • Caching of data cross-app
  • Realtime updates cross-app
  • Options to revalidate data on mount and on focus of browser
  • Fallback Data support for server-side rendering
  • Conditional Fetching
  • Global Config Provider
  • Global Config Retreival Hook

Good to haves but not a part of the bundle yet

  • Error Retries

Usage

Simple Usage

useFetch(
    key: string | null,
    options?: {
        revalidateOnMount?: boolean,
        revalidateOnFocus?: boolean,
        dedupingInterval?: milliseconds,
        fallbackData?: any,
        fetcher?: (key: string) => Promise<any>;
	    dedupingInterval?: number;
	    onSuccess?: (data: any, key: string | null, config: options) => any;
	    onError?: (error: Error, key: string | null, config: options) => any;
    }
)
import useFetch from "use-fetch";

const Component = () => {
	const { data, error, isValidating, revalidate } = useFetch("/api/v1/data");

	if (isValidating) return "Loading";
	if (error) return `Error: ${error.message}`;
	return (
		<>
			Data: {data}
			<Button onClick={() => revalidate()}>Refetch</Button>
		</>
	);
};

Revalidation

Use

revalidate(newDate?: any, refetchFromAPI?: boolean)

Every revalidation fetches data from the API in the background, you can disable that by passing false as the second argument.

const { data, revalidate } = useFetch("/api/v1/data");

revalidate(); // Just make the API call again and populate the cache
revalidate(localData); // Set the data and cache to localData, but make API Call in the background to update with real data. Like Optimistic Rendering
revalidate(localData, false); // Set the data and cache to localData and do not make an API Call in the background

Config Provider

For multiple useFetch hooks, it's cumbersome to pass config/options to each of them separately. Hence, use-fetch comes with a FetchProvider context provider to share the config among all hooks.

import { FetchProvider } from "use-fetch";

return (
	<FetchProvider
		value={{
			revalidateOnMount: boolean,
			revalidateOnFocus: boolean,
			dedupingInterval: number(milliseconds),
			fallback: Record<string, any>,
			fetcher: (key) => any,
			dedupingInterval: number,
		}}
	>
		... All components containing useFetch hooks
	</FetchProvider>
);

Global Config Hook

Retrieve the global config for your fetcher hooks using the useFetchConfig hook.

import { useFetchConfig } from "use-fetch";

const {
	revalidate,
	fetcher,
	fallback,
	cache,
	dedupingInterval,
	revalidateOnMount,
	revalidateOnFocus,
} = useFetchConfig();

// This revalidate works differently.
// It takes 3 args instead of 2.
revalidate(
    keyOfFetcherYouWantToUpdate,
    localData?,
    refetchFromAPI?
);

Fallback Data for SSR/SSG

const key = "/api/v1/data";

const Page = ({ fallbackData }) => {
	const { data } = useFetch(key, { fallbackData: fallbackData[key] });

	// or
	return (
		<FetchProvider value={{ fallback: fallbackData }}>
			{/* 
            All hooks internally would either use their on fallback data or the fallback data from the above provider corresponding to their keys. 
        */}
			...
		</FetchProvider>
	);
};

export const getStaticProps = async () => {
	const data = await fetchData(key);
	return { props: { fallbackData: { [key]: data } } };
};

export default Page;

Handling errors and success

Use the onSuccess and onError handlers for handling the completion and error-ing of the API Calls.

useFetch("/api/v1/data", {
	onSuccess: (data, key, config) => {
		console.log("Data fetched:", data);
	},
	onError: (error, key, config) => {
		console.log("Error while fetching:", error);
	},
});

Or you could use reactivity to your advantage.

useEffect(() => {
	if (data !== undefined) console.log("Data fetched:", data);
}, [data]);

useEffect(() => {
	if (error !== undefined) console.log("Error while fetching:", error);
}, [error]);

About

A Simple hook-based fetcher and caching implementation for React, inspired by SWR

Topics

Resources

Stars

Watchers

Forks

Morty Proxy This is a proxified and sanitized view of the page, visit original site.