我试图将数据提取移到组件文件的自定义钩子上,以便更好地组织代码,但当与上下文结合使用时,钩子不起作用。
这是我的AuthContext.tsx文件
import React, { createContext, useEffect, useState } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { auth } from '../firebase.config';
export const UserContext = createContext<any>({});
export const AuthContextProvider = ({ children }: any) => {
const [currentUser, setCurrentUser] = useState<unknown | null>({});
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
setCurrentUser(user);
});
return () => {
unsub();
};
}, []);
return <UserContext.Provider value={{ currentUser }}>{children}</UserContext.Provider>;
};
这是我的useRooms.ts文件(我的钩子)
import * as React from 'react';
import { collection, query, where, getDocs, QueryDocumentSnapshot, DocumentData } from 'firebase/firestore';
import { db } from '../firebase.config';
import { UserContext } from '../context/AuthContext';
import { RoomsResult } from './types';
export default function useRooms(): RoomsResult {
const [userRooms, setUserRooms] = React.useState<string[] | null>(null);
const [isLoading, setIsLoading] = React.useState(true);
const { currentUser } = React.useContext(UserContext);
const userRoomsQuery = query(collection(db, 'rooms'), where('user', 'array-contains', currentUser.uid));
const fetchUserRoomsData = async () => {
setIsLoading(true);
const userRoomsDocs = await getDocs(userRoomsQuery);
setUserRooms(userRoomsDocs.docs.map((doc: QueryDocumentSnapshot<DocumentData>) => doc.id));
setIsLoading(false);
};
console.log(userRooms);
return { rooms: userRooms, loading: isLoading, fetchUserRoomsData };
}
我收到的错误是:
至于在错误中看到的那些文件名,它们都来自我的App.tsx文件
import React, { useContext } from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { UserContext } from './context/AuthContext';
import { SignUpForm, LogInForm, ChatRooms } from './components/exporter';
type Styles = {
wrapper: string;
};
function App() {
const styles: Styles = {
wrapper:
'bg-purple-200 h-[100vh] w-[100vw] grid grid-cols [minmax(100px,_250px)_1fr_minmax(150px,_250px)] grid-rows-[85%_minmax(50px,_350px)] absolute',
};
const { currentUser } = useContext(UserContext);
const ProtectedRoute = ({ children }: any) => {
if (!currentUser) {
return <Navigate to="/login" />;
} else return children;
};
return (
<BrowserRouter>
<Routes>
<Route
path="/"
element={
<ProtectedRoute>
<div id="portal-container">
<ChatRooms />
</div>
</ProtectedRoute>
}
></Route>
<Route path="login" element={<LogInForm />} />
<Route path="signup" element={<SignUpForm />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</BrowserRouter>
);
}
export default App;
只要我不使用useRooms.ts文件中的const { currentUser } = React.useContext(UserContext);
行,钩子本身就可以工作,但一旦我使用了,我就会在picutre中收到错误。**我将自定义钩子useRooms的使用放在我的组件中,可以看到它呈现为App.tsx中最嵌套的元素。**是否知道是什么导致了这种情况,为什么?
1条答案
按热度按时间slmsl1lt1#
我设法通过将AuthContextProvider中currentUser的默认状态设置为
null
而不是{}
来修复此问题不幸的是,这使得当我刷新我的网页时,它现在忘记了登录的用户。但这可能是预期的行为,直到我检查Firebase Auth文档。