Last active
March 19, 2022 00:46
-
-
Save ChemaCLi/4b33d3f812060e6890dbe58c285ac01b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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