React组件页面加载/卸载API调用异常排查请求
问题排查与修复:React页面加载API重复调用及卸载逻辑异常
问题描述
我希望通过React组件实现:特定页面加载时仅调用一次API,用户导航至其他页面(页面卸载时)再调用一次API。但编写的ActivityTracker组件出现两个问题:页面加载时API调用两次,未卸载页面就触发卸载API调用。
原代码
function ActivityTracker() { // Function to make the API call on page load const onPageLoad = async () => { try { const response = await fetch( 'https://jsonplaceholder.typicode.com/todos/1' ); const data = await response.json(); // Handle the data as needed } catch (error) { console.error('Error on page load:', error); } }; // Function to make the API call on page unload const onPageUnload = async () => { try { const response = await fetch( 'https://jsonplaceholder.typicode.com/todos/1' ); const data = await response.json(); // Handle the data as needed } catch (error) { console.error('Error on page unload:', error); } }; useEffect(() => { onPageLoad(); }, []); return <div>Your page content goes here</div>; } export default ActivityTracker;
问题分析
页面加载API调用两次
- 核心原因是React 18+的严格模式(StrictMode):开发环境下,StrictMode会对组件进行两次渲染,用于检测潜在的副作用问题,因此空依赖的
useEffect会执行两次,导致API调用重复。 - 额外排查点:检查父组件(如App.js)是否重复挂载了
ActivityTracker组件。
- 核心原因是React 18+的严格模式(StrictMode):开发环境下,StrictMode会对组件进行两次渲染,用于检测潜在的副作用问题,因此空依赖的
未卸载就触发卸载API
- 原代码未实现卸载时的API调用逻辑:没有在
useEffect的清理函数中绑定onPageUnload。若出现提前触发的情况,大概率是组件被意外卸载/重建(比如父组件状态变化导致重渲染,组件被销毁后重新挂载)。
- 原代码未实现卸载时的API调用逻辑:没有在
修复方案
修复后的完整代码
function ActivityTracker() { // 页面加载时的API调用 const onPageLoad = async () => { try { const response = await fetch('https://jsonplaceholder.typicode.com/todos/1'); const data = await response.json(); console.log('页面加载API返回数据:', data); } catch (error) { console.error('页面加载API调用失败:', error); } }; // 页面卸载时的API调用 const onPageUnload = async () => { try { // 关键:unload事件中需配置keepalive,避免请求被浏览器中断 const response = await fetch('https://jsonplaceholder.typicode.com/todos/1', { keepalive: true }); const data = await response.json(); console.log('页面卸载API返回数据:', data); } catch (error) { console.error('页面卸载API调用失败:', error); } }; useEffect(() => { // 页面加载时执行一次API调用 onPageLoad(); // 定义清理函数,组件卸载时自动执行 return () => { onPageUnload(); }; }, []); return <div>页面内容</div>; } export default ActivityTracker;
关键修复说明
解决加载时重复调用:
- 开发环境下StrictMode的两次渲染是正常检测机制,生产环境不会出现。若需在开发环境临时避免,可移除根组件外的
<StrictMode>标签(不推荐长期移除,建议保留以检测副作用)。 - 确保
ActivityTracker在父组件中仅被挂载一次。
- 开发环境下StrictMode的两次渲染是正常检测机制,生产环境不会出现。若需在开发环境临时避免,可移除根组件外的
实现正确的卸载调用逻辑:
- 在
useEffect的返回值中定义清理函数,组件卸载时会自动执行该函数,触发onPageUnload。 - 添加
keepalive: true配置:页面卸载时(如关闭浏览器、导航跳转),浏览器可能中断未完成的请求,该配置可确保请求能成功发送至服务器。
- 在
内容的提问来源于stack exchange,提问作者Dhanesh Mane
相关产品推荐
相关产品推荐

