如何更改react(fetch hook)中钩子的参数



我的提取挂钩:

import { useEffect, useState } from "react";
export const useOurApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
const [fetchedData, setFetchedData] = useState(initialData);
useEffect(() => {
let unmounted = false;
const handleFetchResponse = response => {
if (unmounted) return initialData;
setHasError(!response.ok);
setIsLoading(false);
return response.ok && response.json ? response.json() : initialData;
};
const fetchData = () => {
setIsLoading(true);
return fetch(url, { credentials: 'include' })
.then(handleFetchResponse)
.catch(handleFetchResponse);
};
if (initialUrl && !unmounted)
fetchData().then(data => !unmounted && setFetchedData(data));
return () => {
unmounted = true;
};
}, [url]);
return { isLoading, hasError, setUrl, data: fetchedData };
};

我在一个函数中这样调用这个钩子:

//states
const [assignments, setAssignments] = useState([])
const [submissions, setSubmissions] = useState([])
const [bulk_edit, setBulk_edit]     = useState(false)
const [ENDPOINT_URL, set_ENDPOINT_URL]  = useState('https://jsonplaceholder.typicode.com/comments?postId=1')
let url = 'https://jsonplaceholder.typicode.com/comments?postId=1';
const { data, isLoading, hasError } = useOurApi(ENDPOINT_URL, []); 

我的问题是如何用不同的URL调用这个userOurAPI实例。我试过在需要的函数中调用它,但我们不能在函数中调用钩子,所以我不知道如何给它传递新的url来获得新的数据。我不想有很多userOurAPI的实例,因为这不是DRY。或者这是不可能的?钩子新手,所以对我宽容一点!

为了更改URL以使组件更新并获取新数据,您创建了一个更改URL的set函数,并确保在更改URL时再次运行useEffect((。返回URL的setter函数,这样您就可以在钩子的第一个实例之外使用它。在我的代码中,你会看到我返回了一个setUrl,我可以用它来更新fetch!我真傻,没注意到,但希望这能帮助到别人。

可以按照您选择的方式进行操作,但还有其他方法可以解决此问题。

另一种方法是,每当URL发生变化时,总是重新获取,而不需要从钩子返回显式的setter。这看起来像这样:

export const useOurApi = (url, initialData) => { // URL passed directly through removes the need for a specific internal url `useState`
// const [url, setUrl] = useState(initialUrl); // No longer used
// ...
useEffect(() => {
// Handle fetch
}, [url]);
return { isLoading, hasError, data: fetchedData }; // No more `setUrl`
};

不过,这可能并不总是你想要的,有时你可能不想在每次url更改时重新获取所有数据,例如,如果url为空,你可能不希望更新url。在这种情况下,您只需向useOurApi自定义挂钩添加一个useEffect即可更新内部url并重新获取:

export const useOurApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
// ...
useEffect(() => {
// Handle fetch
}, [url]);
useEffect(() => {
// ... do some permutation to the URL or validate it
setUrl(initialUrl);
}, [initialUrl]);
return { isLoading, hasError, data: fetchedData }; // No more `setUrl`
};

如果有时仍然想重新获取与URL无关的数据,可以从钩子输出一些函数来触发数据获取。类似这样的东西:

export const useOurApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
const [fetchedData, setFetchedData] = useState(initialData);
const refetch = useCallback(() => {
// Your fetch logic
}, [url]);
useEffect(() => {
refetch(); // In case you still want to automatically refetch the data on url change
}, [url]);
return { isLoading, hasError, refetch, data: fetchedData };
};

现在,只要您想触发重新获取,就可以调用refetch。您可能仍然希望能够在内部更改url,但这为您提供了另一个更灵活的获取权限以及何时进行获取。

您混淆了简单函数函数组件功能组件不仅仅是简单函数。这意味着必须返回组件或html标签

我认为你应该把四个函数变成像这样的简单函数

export const useOurApi = (initialUrl, initialData) => {
let url = initialUrl, fetchedData = initialData, 
isLoading= true, hasError = false, unmounted = false;
const handleFetchResponse = response => {
if (unmounted) return initialData;
hasError = !response.ok;
isLoading = false;
return response.ok && response.json ? response.json() : initialData;
};
const fetchData = () => {
isLoading = true;
return fetch(url, { credentials: 'include' })
.then(handleFetchResponse)
.catch(handleFetchResponse);
};
if (initialUrl && !unmounted)
fetchData().then(data => {
if(!unmounted) fetchedData =data;
unmounted = true;
});
return { isLoading, hasError, url, data: fetchedData };
};

相关内容

  • 没有找到相关文章

最新更新