简体   繁体   中英

React hooks with async fetch

I'm new to React hooks, but I'm trying to use a useEffect with a useCallback , but getting the notorious React Hook "useList" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks React Hook "useList" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function react-hooks/rules-of-hooks error.

Thie file holds the makeRequest:

function useConnections = () => {
    const makeRequest = React.useCallback(async (props) => {
        // Determine base url, determine headers here
        const response = fetch(url, options);

        return response;
    }

    return { makeRequest };
}

This file is my useListProvider :

function useListProvider = () => {
    const { makeRequest } = useConnections();

    const useList = React.useCallback(async (props) => {
        // makerequest is just a wrapper for fetch with a bunch of needed headers.
        const response = await makeRequest(props);

        return { body: response.body };
    }

    return { useList };
}

This is the rendered page:

function MainPage() {
    const [isBusy, setIsBusy] = React.useStore(false);
    const { useList } = useListProvider();

    React.useEffect(() => {
        if (!isBusy) { useList(); setIsBusy(false); } // ERROR HERE!
    }, [useList]);

    return (
        <React.Fragment>
            IsBusy: {isBusy}
        </React.Fragment>
    );
}

Maybe I'm not getting it, but I only want to grab the useList data when the state says it's not busy. However, doing it this way, I get the error listed above. I understand I can't think of this the same way as Component classes, but how would you approach single and multiple renders from a callback?

I'm not entirely sure what is happening here because I'm doing something similar in the useConnections, etc. and not getting the same error?

The lint rule for hooks assumes that things which start with "use" are hooks. Thus it thinks that useList is a hook and trying to enforce the rules of hooks on it. But it's not actually a hook, it's just a normal function, so you just need to give it a different name and the lint rule will be satisfied.

function useListProvider = () => {
    const { makeRequest } = useConnections();

    const callback = React.useCallback(async (props) => {
        const response = await makeRequest(props);

        return { body: response.body };
    }, [makeRequest])

    return { callback };
}

// elsewhere:

const { callback } = useListProvider();

React.useEffect(() => {
    if (!isBusy) { 
      callback(); 
      setIsBusy(false);
    }
}, [callback]);

Why is it not a hook? Well, a hook is either one of the built in hooks, or a function that calls one of the built in hooks. Your callback doesn't meet those criteria. It was created by useCallback, but that just means it's a memoized function, not a hook.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM