Skip to content

Instantly share code, notes, and snippets.

@vcanales
Created April 7, 2021 15:05
Show Gist options
  • Save vcanales/42a2019f5ee6a4e5a4495b7c060f1fba to your computer and use it in GitHub Desktop.
Save vcanales/42a2019f5ee6a4e5a4495b7c060f1fba to your computer and use it in GitHub Desktop.
Fetch provider, and context based request status.

Fetch Provider

A fetch wrapper that provides a function that allows obtaining the request status wherever it is used, through the React context API.

import FetchProvider, { useRequestStatus } from '../components/fetch-provider';
export default function Create() {
const { loading, fetch } = useRequestStatus();
async function publishCatalogue() {
try {
const data = await fetch('/endpoint');
// do somthing with the data
} catch(e) {
// handle errors
}
}
return (
<FetchProvider>
<button onClick={}>Fetch something</button>
{loading && <div>Loading...</div>}
{data && <div>{data}</div>
</FetchProvider>
);
}
import { createContext, Component, useContext } from 'react';
import fetch from 'isomorphic-unfetch';
const FetchContext = createContext();
const { Provider } = FetchContext;
export class FetchProvider extends Component {
constructor(props) {
super(props);
this.controlledFetch = this.controlledFetch.bind(this);
this.state = {
loading: false,
};
}
async controlledFetch(url, options) {
this.setState({ loading: true });
try {
const response = await fetch(url, options);
const data = await response.json();
return data || null;
} finally {
this.setState({ loading: false });
}
}
render() {
const { loading } = this.state;
const { children } = this.props;
return (
<Provider value={{ loading, fetch: this.controlledFetch }}>
{children}
</Provider>
);
}
}
export function useRequestStatus() {
const ctx = useContext(FetchContext);
if (!ctx) {
throw new Error(
'`useContext` can only be called within a child of `FetchProvider`'
);
}
return { loading: ctx.loading, fetch: ctx.fetch };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment