Skip to content

Instantly share code, notes, and snippets.

@ChemaCLi
Last active March 19, 2022 00:46
Show Gist options
  • Select an option

  • Save ChemaCLi/4b33d3f812060e6890dbe58c285ac01b to your computer and use it in GitHub Desktop.

Select an option

Save ChemaCLi/4b33d3f812060e6890dbe58c285ac01b to your computer and use it in GitHub Desktop.
import { useRef, useEffect } from "react";
// Hook taken from here https://usehooks.com/usePrevious/
export function usePrevious(value) {
// The ref object is a generic container whose current property is mutable ...
// ... and can hold any value, similar to an instance property on a class
const ref = useRef();
// Store current value in ref
useEffect(() => {
ref.current = value;
}, [value]); // Only re-run if value changes
// Return previous value (happens before update in useEffect above)
return ref.current;
}
import { useEffect, useState } from "react";
import { usePrevious } from "./use-previous";
/**
* @param {function} serviceFunction Fetch function
* @param {object} args Params passed to the function
* @param {{ shouldFetch: boolean }} suspense If passed, hook won't try
* to perform the fetch until shouldFetch property is true
*/
export function useService(
serviceFunction,
args = {},
suspense = undefined
) {
const [state, setState] = useState({
loading: true,
data: null,
error: null
});
const setLoading = (loading = false) => {
setState(prevState => ({ ...prevState, loading }));
};
const setError = (error = null) => {
setState(prevState => ({ ...prevState, error }));
};
const setData = (data = null) => {
setState(prevState => ({ ...prevState, data }));
};
const performQuery = async newArgs => {
setLoading(true);
try {
const data = await serviceFunction(newArgs || args);
setData(data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
// Needed to check only once the suspense config to avoid
// an infinite loop
const initialShouldFetch = usePrevious(suspense?.shouldFetch);
useEffect(() => {
if (suspense === undefined)
performQuery().then();
else if (suspense?.shouldFetch !== initialShouldFetch
&& !!suspense?.shouldFetch) {
performQuery().then();
}
}, [suspense]);
return { ...state, refetch: performQuery };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment