我正在尝试使用自定义挂钩来发出HTTP请求,然后使用reducer来更新组件中的状态。
钩子运行正确,我可以从请求中获得响应,但不能在dispatch函数中使用响应数据。
以下是代码:
HTTP挂钩:
import React, { Fragment, useState, useEffect, useReducer } from 'react';
import axios from 'axios';
export const useHttpRequest = (initialData, initialURL) => {
const [url, setUrl] = useState(initialURL);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
console.log('in a http hook');
setIsError(false);
try {
const res = await axios(url);
console.log(res);
const responseData = res.data.data.data;
return responseData;
} catch (error) {
setIsError(true);
}
};
fetchData();
}, [url]);
return { isError, setUrl };
};
状态下的函数调用:
const { isError, setUrl } = useHttpRequest();
const getCategoryData = async () => {
setLoading();
try {
const Data = await setUrl('/api/v1/category');
dispatch({
type: SET_CATEGORYDATA,
payload: Data
});
} catch (err) {}
};
组件中的函数调用,其中函数通过useContext 传递
useEffect(() => {
getCategoryData();
}, []);
- 不能在
setState
(setUrl
(函数上使用await
- 您在获取数据时返回的数据以后不会使用
你需要首先改变你在反应挂钩中的思维方式以及何时需要使用它们。
据我所知,您希望从服务器获取一些数据,在成功检索时更新存储,并在请求失败时显示错误。
你应该一直这样做,或者根本不这样做。您可以将调度放在钩子中或您可以忘记钩子,编写一个可重用的fetchData
函数并在组件的useEffect
中处理setHasError
。
有很多方法可以解决这个问题,但这是我的首选解决方案:
import React, { Fragment, useState, useEffect, useReducer } from 'react';
import axios from 'axios';
export const useHttpRequest = (url, updateStore) => {
const [hasError, setHasError] = useState(false);
const fetchData = async (url) => {
setHasError(false);
try {
const res = await axios(url);
const responseData = res.data.data.data;
updateStore(responseData);
} catch (error) {
setHasError(true);
}
};
useEffect(() => {
if (url) {
fetchData(url);
}
}, [url]);
return { fetchData, hasError };
};
// in case you want to fetch the data on component render
const { fetchData, hasError } = useHttpRequest(url, (data) => dispatch({
type: SET_CATEGORYDATA,
payload: data
}));
// in case you want to fetch it in a callback
const clickButton = () => {
fetchData(someCustomUrl);
}
最后,您可以泛化您的调度器,这样您就不需要将整个函数发送到钩子,只需要发送调度器名称。