为什么我的分析工具会记录两次每次页面访问(以及我是如何修复的)

发布日期:2026-06-01 10:02:13   浏览量 :5
发布日期:2026-06-01 10:02:13  
5

2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家 

我在我的作品集后端中构建了一个自定义分析系统——一个记录页面访问的 Django REST API,并将 React 前端连接到该系统,以便在有人访问项目或博客文章详情页时调用它。系统运行正常,但存在一个问题:每次访问都被记录了两次。

这个故事讲述了如何追逐错误的根本原因,在一个无效的修复方案上浪费时间,最终找到一个完全独立于 React 之外的极其简单的解决方案。

背景设置

后端是一个带有 PageVisit 模型的 Django REST API。每当用户访问详情页时,前端都会调用一个端点:

// POST /api/analytics/track/
{ "page_type": "project", "object_id": 33 }

在 React 端,该调用位于 ProjectPage 组件内的 useEffect 钩子中:

useEffect(() => {
  if (project?.id) api.trackPageView('project', Number(project.id));
}, [project?.id]);

项目数据来自一个 useProject 自定义钩子,该钩子首先从 localStorage 缓存中读取数据,然后从 API 获取数据。

症状表现

访问两个项目页面后,管理后台显示了以下内容:

637  Project  33
636  Project  33
635  Personal Projects  -
634  Project  30
633  Project  30

每次访问项目页面都会产生两条记录。

首要嫌疑对象:React 严格模式

我的第一反应是 React 严格模式(StrictMode)。在开发环境中,<React.StrictMode> 会故意双重调用副作用钩子以暴露潜在的副作用问题——它会挂载组件,执行清理函数,然后重新挂载组件。如果副作用钩子在初始挂载和模拟重新挂载时都触发了,这就解释了为什么每次访问会产生恰好两条记录。

标准的修复方法是使用 useRef 进行防护:将最后跟踪的 ID 存储在 ref 中,如果 ID 匹配则跳过调用。

const trackedProjectId = useRef<string | null>(null);

useEffect(() => {
  if 

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
支持 反馈 订阅 数据
回到顶部