如何正确调用useFetch函数?



我已经成功地实现了一个useFetch函数来调用API端点。 如果我像这样将这样的代码添加到函数式 React 组件的根中,它会完美运行:

const [{ data, isLoading, isError }] = useFetch(
'http://some_api_endpoint_path'
);
export const useFetch = (url) => {
const [data, setData] = useState();
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const response = await axios.get(url);
setData(response.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
fetchData();
}, [url]);
return [{ data, isLoading, isError }];
};

但是,假设我想检查新输入的username是否存在,例如在触发输入元素的onBlur事件时。 当我尝试实现这个时,我收到此错误:

React Hook "useFetch" is called in function "handleBlur" which is neither a React function component or a custom React Hook function  react-hooks/rules-of-hooks

我什至尝试了这种方法:

const [isChanged, setIsChanged] = useState(false);
useEffect(() => {
useFetch(
'http://some_api_endpoint_path'
);
}, [isChanged]);

但得到了同样的错误。

然后我尝试了这个简化版本,它没有任何用处,但我正在测试 React Hooks 规则:

useEffect(() => {
useFetch(
'http://some_api_endpoint_path'
);
}, []);

我仍然得到同样的错误。

特别是在最后 2 种情况下,我觉得我遵循了钩子规则,但显然没有!

在这种情况下,如何正确称呼useFetch

我想你这样称呼useFetch,对吧?

const onBlur = () => {
const [{ data, isLoading, isError }] = useFetch(
'http://some_api_endpoint_path'
);
...
}

如果这是真的,这是错误的。查看此链接:

🔴 不要调用事件处理程序。

您可以通过以下方式实现:

// Pass common initial for all fetches.
export const useFetch = (awsConfig, apiRoot, apiPathDefault) => {
const [data, setData] = useState();
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
// Just pass the variables that changes in each new fetch requisition
const fetchData = async (apiPath) => {
setIsError(false);
setIsLoading(true);
try {
const response = await axios.get(apiRoot + apiPath);
setData(response.data);
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
useEffect(() => {
fetchData(apiRoot + apiPathDefault);
}, [awsConfig, apiRoot, apiPathDefault]);
return [{ data, isLoading, isError }, fetchData];
};

每当您想再次获取时,只需拨打fetchData

const [{ data, isLoading, isError }, fetchData] = useFetch(API_ROOT(), appStore.awsConfig, defaultPath);
const onBlur = () => {
fetchData(newPath);
...
}

我使用了与阿波罗团队在创建useLazyQuey时使用的相同原理(请打开此链接并搜索useLazyQuery(。另外,请注意,当我调用钩子时,我会传递所有常见和不可变的变量,并在单个获取中只传递可变变量。

相关内容

  • 没有找到相关文章

最新更新