Next.js页面刷新报错:Cannot read properties of undefined (reading 'indexOf')
问题排查与解决方案
原因分析
刷新页面触发错误的核心问题出在Firebase Auth的状态初始化时机:
useAuthState在组件挂载/刷新时,会先返回undefined(因为Firebase需要异步恢复用户的登录状态),此时user?.uid同样是undefined。- 你在组件顶层直接创建
folderColRef,当user为undefined时,传给collection的路径参数无效(第三参数是undefined),这会导致getDocs调用时,Firebase内部处理路径字符串时抛出indexOf相关错误——因为undefined没有字符串方法。 - 你的
useEffect依赖是空数组,只会执行一次,刚好赶在user未初始化完成时触发,所以刷新时必现错误;而初次运行可能因为auth状态已缓存,user能快速获取到值,所以暂时正常。
解决方案
核心思路是:确保只有user存在时才创建有效数据库引用并发起请求,同时让useEffect监听user的状态变化,自动重新执行数据获取逻辑。
修改后的基础代码
const [folders, setFolders] = useState([]); const [user] = useAuthState(auth); useEffect(() => { // user未加载完成时直接返回,避免无效请求 if (!user) return; const getFolders = async () => { // 将引用创建移到内部,确保仅在user存在时生成有效路径 const folderColRef = collection(db, "UsersData", user.uid, "Folders"); const userData = await getDocs(folderColRef); setFolders(userData.docs.map((doc) => ({ ...doc.data(), id: doc.id }))); }; getFolders(); }, [user]); // 依赖添加user,user状态变化时重新执行
额外优化:添加加载状态
可以增加加载状态避免页面出现异常:
const [folders, setFolders] = useState([]); const [user] = useAuthState(auth); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const getFolders = async () => { setIsLoading(true); if (!user) { setIsLoading(false); return; } const folderColRef = collection(db, "UsersData", user.uid, "Folders"); const userData = await getDocs(folderColRef); setFolders(userData.docs.map((doc) => ({ ...doc.data(), id: doc.id }))); setIsLoading(false); }; getFolders(); }, [user]); // 渲染时根据加载状态显示提示 if (isLoading) return <div>加载中...</div>;
内容的提问来源于stack exchange,提问作者Mintee
相关产品推荐
相关产品推荐

