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