使用功能作为反应挂钩?

时间:2020-02-19 09:10:21

标签: javascript reactjs react-hooks reactn

我想使用一个函数作为React Hook,将获取请求包装到API。

我当前的钩子:

export function useAPI(url, options={}) {
    const [auth, setAuth] = useGlobal('auth');
    const [call, setCall] = useState(undefined);

    const apiFetch = async () => {
        const res = await fetch(url, {
            ...options,
        });
        if (!res.ok)
            throw await res.json();
        return await res.json();
    };

    function fetchFunction() {
        fetch(url, {
            ...options,
        });
    }

    useEffect(() => {
        // Only set function if undefined, to prevent setting unnecessarily
        if (call === undefined) {
            setCall(fetchFunction);
            //setCall(apiFetch);
        }

    }, [auth]);

    return call
}

这样,在react函数中,我可以执行以下操作...

export default function LayoutDash(props) {
    const fetchData = useAPI('/api/groups/mine/'); // should return a function

    useEffect(() => {
        fetchData(); // call API on mount
    }, []);

    render(...stuff);
}

但是似乎react无法使用此类钩子中的函数。如果将call设置为fetchFunction,它将返回undefined。如果将其设置为apiFetch,它将执行并返回一个Promise,而不是我想在其他组件中调用的函数。

起初,我去使用React挂钩是因为我不能在React组件/挂钩外部使用useGlobal。而且我需要访问reactn全局变量auth来检查访问令牌是否已过期。

那么解决这个问题的最佳方法是什么?最终目标是能够将(url, options)传递给某个函数,该函数将成为获取请求的包装器。 (它检查auth.access是否到期,如果到期,则首先获取新的访问令牌,然后进行api调用,否则仅进行API调用)。我想知道,除了反应钩子之外,还有其他方法可以解决这个问题。

1 个答案:

答案 0 :(得分:0)

可以考虑使用useState,而不是将函数放入useCallback中。您的代码如下所示:

export function useAPI(url, options={}) {
    const [auth, setAuth] = useGlobal('auth');

    function fetchFunction() {
        fetch(url, {
            ...options,
        });
    }

    const call = useCallback(fetchFunction, [auth]);


    const apiFetch = async () => {
        const res = await fetch(url, {
            ...options,
        });
        if (!res.ok)
            throw await res.json();
        return await res.json();
    };

    return call
}

只要auth发生更改,就会重新创建返回的函数,因此在某种程度上模仿了您尝试使用useEffect进行的操作