如何在React生命周期方法中检测IndexedDB是否已存在
正确检测IndexedDB是否存在的方法
我来帮你排查下之前代码的问题,然后给出靠谱的解决方案~
你之前代码的核心问题
你的代码逻辑出错主要是因为 IndexedDB的操作是异步的,onupgradeneeded 是异步触发的事件,但你在 componentDidMount 里同步判断 dbExists 的值——这时候异步事件还没执行,dbExists 还是初始的 true,所以不管数据库是否存在,都会先执行 this.setState({redirect: true})。
另外,onupgradeneeded 不仅会在数据库不存在时触发,当你打开的数据库版本高于现有版本时也会触发,你之前的代码没有区分这两种情况,所以才会出现数据库已存在但仍打印“Does not exist”的问题。
解决方案一:利用 onupgradeneeded 和 onsuccess 事件(兼容性好)
通过事件对象的 oldVersion 属性可以准确判断数据库是否是首次创建(也就是之前不存在):
componentDidMount() { let dbExists = true; const openReq = indexedDB.open("dbName"); // 仅在数据库不存在(或版本需升级)时触发 openReq.onupgradeneeded = (e) => { // oldVersion 为 0 说明是首次创建数据库,即之前不存在 if (e.oldVersion === 0) { dbExists = false; console.log("数据库不存在"); // 取消创建数据库(如果不需要自动创建的话) e.target.transaction.abort(); } else { // 这里是版本升级的场景,不是数据库不存在 console.log("数据库版本需要升级"); } }; openReq.onsuccess = () => { if (dbExists) { console.log("数据库已存在"); this.setState({ redirect: true }); } else { this.setState({ redirect: false }); } // 记得关闭数据库连接,避免内存泄漏 openReq.result.close(); }; openReq.onerror = (e) => { console.error("打开数据库出错:", e); this.setState({ redirect: false }); }; }
解决方案二:使用 indexedDB.databases()(更直观,现代浏览器支持)
这个方法会返回一个Promise,包含当前所有已存在的数据库列表,直接检查即可:
async componentDidMount() { try { // 获取所有已存在的数据库 const databases = await indexedDB.databases(); // 判断目标数据库是否在列表中 const dbExists = databases.some(db => db.name === "dbName"); if (dbExists) { console.log("数据库已存在"); this.setState({ redirect: true }); } else { console.log("数据库不存在"); this.setState({ redirect: false }); } } catch (error) { console.error("获取数据库列表出错:", error); this.setState({ redirect: false }); } }
注意:indexedDB.databases() 不支持IE浏览器,但Chrome、Firefox、Edge等现代浏览器都已支持。
内容的提问来源于stack exchange,提问作者jsDev
相关产品推荐
相关产品推荐

