React项目构建成功后出现Uncaught Runtime Error问题求助
React运行时错误:Uncaught TypeError: Cannot read properties of null (reading 'indexOf')
构建React项目无报错,但启动应用后出现如下运行时错误:
Uncaught TypeError: Cannot read properties of null (reading 'indexOf') at ut.fromString (index.esm2017.js:1032:1) at gh (index.esm2017.js:17952:1) at Layout.js:377:1 at Array.forEach (<anonymous>) at Array.<anonymous> (Layout.js:373:1) at next (index.esm2017.js:20677:1) at index.esm2017.js:16739:1
相关代码片段(Layout.js中的useEffect逻辑):
useEffect(() => { if (localStorage.getItem("userdata")) { setUserRole(JSON.parse(localStorage.getItem("userdata")).role); } const unsubscribe = onSnapshot(collection(db, "supportRoom"), (snapshot) => { if (snapshot.docs.length == 0) { setHelpCall(false); setHelpCaller({}); } else { const allData = snapshot.docs.map((doc) => ({ id: doc.id, ...doc.data(), })); allData.forEach((docs) => { if (docs.response == false && docs.reciever == "") { setSupportRoomData(supportRoomData); setHelpCall(true); const docRef = doc(db, "users", docs.creater); getDoc(docRef).then((doc) => { setHelpCaller(doc.data()); setHelpCallerId(doc.id); }); } else { setHelpCall(false); } }); } }); return () => { // cancelHelpCall() unsubscribe(); }; }, [userData]);
已尝试操作:检查Firebase数据获取、清理缓存、重新安装依赖,问题仍未解决。
解决建议
校验Firebase文档引用的合法性
错误栈指向Firebase内部的fromString方法,大概率是docs.creater为null/空值,导致生成无效的文档引用。添加前置校验:if (docs.response == false && docs.reciever == "" && docs.creater) { // ...其他逻辑 const docRef = doc(db, "users", docs.creater); // ...后续操作 }处理getDoc返回的空文档
当查询的用户文档不存在时,doc.data()会返回null,若后续代码依赖helpCaller调用indexOf就会触发错误。给返回值设置默认空对象:getDoc(docRef).then((doc) => { setHelpCaller(doc.data() || {}); setHelpCallerId(doc.id); });修复state更新的逻辑问题
代码中setSupportRoomData(supportRoomData)直接使用当前state值更新,属于无效操作且可能引发状态不一致。如果是要追加数据,改用函数式更新:setSupportRoomData(prevState => [...prevState, docs]);修正forEach中的状态覆盖问题
循环中每次迭代都会覆盖helpCall的状态,最终只会保留最后一次迭代的结果。改为先筛选符合条件的请求,再统一处理:const pendingCalls = allData.filter(item => item.response === false && item.reciever === ""); if (pendingCalls.length > 0) { setHelpCall(true); // 取第一个待处理请求,或根据业务需求处理全部 const targetCall = pendingCalls[0]; if (targetCall.creater) { const docRef = doc(db, "users", targetCall.creater); getDoc(docRef).then((doc) => { setHelpCaller(doc.data() || {}); setHelpCallerId(doc.id); }); } } else { setHelpCall(false); setHelpCaller({}); }加固localStorage数据解析逻辑
避免因localStorage数据损坏导致的潜在问题:const userDataStr = localStorage.getItem("userdata"); if (userDataStr) { try { const userData = JSON.parse(userDataStr); if (userData?.role) { setUserRole(userData.role); } } catch (err) { console.error("解析userdata失败:", err); } }
内容的提问来源于stack exchange,提问作者AmericaDoodles
相关产品推荐
相关产品推荐

