Create React App开发环境中IndexedDB onsuccess代码块执行两次问题
为什么开发环境下IndexedDB的onsuccess执行两次,部署后只执行一次?
1. CRA开发服务器的热模块替换(HMR)机制导致
Create React App的开发环境默认启用热模块替换(HMR),修改代码时不会刷新整个页面,只会重载变化的模块。如果你的IndexedDB初始化代码写在模块全局作用域或者组件顶层,HMR重载模块时会再次执行这段代码,导致indexedDB.open被调用两次,进而触发两次onsuccess回调。
而部署到Vercel后是生产构建版本,没有HMR机制,模块仅加载一次,所以onsuccess只执行一次。
2. React Strict Mode的重复检测逻辑
开发环境下CRA默认开启了Strict Mode,这个模式会刻意重复执行组件顶层代码、部分生命周期函数,用于检测潜在的代码问题。如果你的indexedDB.open代码放在组件内部,Strict Mode会让它执行两次,自然触发两次onsuccess。
生产环境下Strict Mode会自动禁用,代码仅执行一次。
验证与解决方法
- 把初始化逻辑放到仅执行一次的上下文:用React的
useEffect搭配空依赖数组,确保组件挂载时只运行一次:
import { useEffect, useState } from 'react'; function YourComponent() { const [db, setDb] = useState(null); useEffect(() => { const DBOpenReq = window.indexedDB.open("todo-todo", 2); DBOpenReq.onsuccess = (event) => { const database = event.target.result; console.log("IndexedDB connection success", database); setDb(database); listProjects(); addProjectsInitally(); }; // 可选:组件卸载时关闭数据库连接 return () => { database?.close(); }; }, []); // 空依赖数组,仅执行一次 // ...其他组件逻辑 }
- 若不需要Strict Mode的检测,可以在
index.js中移除<React.StrictMode>的包裹,但不推荐这么做——它能帮你提前发现潜在的代码问题。
内容的提问来源于stack exchange,提问作者Bikash Pandey
相关产品推荐
相关产品推荐

