[英]Bug in React.js custom fetch hook
我的 React (v18.1.0) 项目中有以下自定义挂钩useFetch
,用于从 Node.js 服务器获取数据。
export default function useFetch(url, requestType, headers, body) {
const [error, setError] = useState(false);
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
console.log('Inside useFetch hook');
useEffect(() => {
console.log('Inside useEffect in the useFetch hook');
const controller = new AbortController();
async function retrieveData(reqUrl) {
try {
console.log('Inside the useFetch try block');
const res = await fetchData(
reqUrl,
requestType,
headers,
body,
controller.signal
);
console.log('Done with fetch; this is the server response ', res);
setData(res);
setLoading(false);
console.log('Done with useFetch try block.');
} catch (err) {
if (err.name === 'AbortError') {
console.log('Fetch aborted');
} else {
setError(true);
setData(err);
setLoading(false);
}
}
}
retrieveData(url);
return () => {
controller.abort();
};
}, []);
return { loading, error, data };
}
我的 useFetch 挂钩使用名为fetchData
的 function 向服务器发送提取请求。
async function fetchData(url, requestType, headers, payload, abortSignal) {
console.log('Inside the fetch function');
let res = await fetch(url, {
method: requestType,
headers: headers,
body: payload,
signal: abortSignal ? abortSignal : null,
});
if (res.ok) {
const resJson = await res.json();
console.log('Returning value from fetch function');
return { status: res.status, response: resJson };
} else {
await fetchErrorHandler(res);
}
}
useFetch
挂钩在我的VideoPlayer
组件中被调用一次。
function VideoPlayer() {
const { videoId } = useParams();
const url = `http://localhost:5000/videos/${videoId}`;
const { loading, error, data } = useFetch(url, 'GET', {}, null);
return (
<div>
{loading && <div />}
{!loading && error && <h2>{data.message}</h2>}
{!loading && !error && (
<video width={600} height={450} controls src={data.response.videoUrl}>
Cannot display video player.
</video>
)}
</div>
);
}
我面临的问题是,当VideoPlayer
组件挂载到 DOM 并useFetch
时,执行流程如下所示: Execution flow of useFetch
hook 。 如图所示,在控制台打印Inside the fetch function
行之前,一切似乎都很好。 此后,再次调用useFetch
中的useEffect
挂钩,原因我无法理解(我的依赖项数组为空,而且此时没有 state 更改)。 然后,它尝试再次执行fetch
,中止它,然后最终返回一个响应,大概是对原始fetch
请求的响应。 在此过程结束时,将再次调用useFetch
。 如果有人能帮助我阐明为什么挂钩会以这种方式运行,而不是简单地执行一次fetch
请求并返回响应,我将不胜感激。
我假设您在StrictMode中使用 React - 这是使用 create-react-app 创建的应用程序的默认设置。
在严格模式下,效果可以在开发模式下触发两次。 您可以通过运行生产构建来验证这是否会导致您的问题。 如果问题消失,则可能是由 StrictMode 引起的。
我的建议是不要更改任何东西——实际上,您的代码似乎工作正常:第一个效果执行触发一次提取,然后第二个效果执行中止初始提取并进行第二次提取。 这正是代码预期执行的操作。
可以用axios来处理API
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.