我在我的react應用中使用Firebase進行認證。我有一個AuthContext,即:
import React, { useContext, useState, useEffect } from 'react;
import { auth, storage, db } from './firebase'。
const AuthContext = React.createContext()。
export function useAuth() {
return useContext(AuthContext)。
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()。
const [currentUserData, setCurrentUserData] = useState();
const [loading, setLoading] = useState(true);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((user) =>/span> {
setCurrentUser(user)。
db.collection('user')
.doc(user.uid)
.onSnapshot((doc) => {
var data = doc.data()。
setCurrentUserData(資料)。
});
setLoading(false)。
});
return unsubscribe;
}, []);
signup function,
login function,
注銷 函式const value = {
currentUser,
currentUserData,
簽到。
登錄
logout,
}
return (
<AuthContext.Provider value={value}> /span>
{!加載&& children}。
</AuthContext.Provider>/span>
);
}
每當我注冊/創建一個新用戶時,我也會在Firestore的'users'集合中創建一個檔案,其中有一些默認的用戶欄位和來自Firebase auth的uid。我有一堆頁面需要從這個 firestore 檔案中獲取當前登錄用戶的一些資料。對于第一個登錄到應用程式的用戶,我可以在currentUserData狀態下獲得這些用戶資料。但是,當一個用戶退出,另一個用戶登錄時,currentUserData狀態持有從fielstore獲取的先前登錄的用戶的值,而不是當前登錄的用戶。我試著建立了一個單獨的DataContext,比如:
。
import React, { useEffect, useState, useContext } from 'react;
import { db } from './firebase'。
import { useAuth } from './AuthContext'。
const DataContext = React.createContext()。
export function useData(){
return useContext(DataContext)。
}
export function DataProvider({ children }) {
const [currentUserData, setCurrentUserData] = useState()。
const [loading, setLoading] = useState(true);
//current user from AuthContext[/span].
const { currentUser } = useAuth() 。
useEffect(() => {
db.collection('user')
.doc(currentUser.uid)
.onSnapshot((doc) =>/span> {
var data = doc.data()。
setCurrentUserData(資料)。
setLoading(false)。
});
}, []);
const value = {
currentUserData,
};
return (
<DataContext.Provider value={value}> /span>
{!加載&& children}。
</DataContext.Provider>/span>
);
}
而在相應的App.js中:
<Router>
<AuthProvider>。
<DataProvider>/span>
<Switch>/span>
< PrivateRoute exact path='/' component={Home} />
.
.
.
</Switch>。
</DataProvider>/span>
</AuthProvider>/span>
</Router>
這樣做也會導致同樣的情況。當一個用戶注銷,另一個用戶登錄時,我在currentUserData狀態中仍有前一個用戶的值。然而,AuthContext中的currentUser狀態卻能正確地作業。我已經厭倦了在每一個需要登錄用戶資料的組件中獲取用戶資料。我想一次性獲取資料,并在任何需要它的組件中使用它。但是,我有問題,使它作業。是不是我做錯了什么?
uj5u.com熱心網友回復:
你可以使用一個類似這樣的減速器(顯然沒有你的'.../firebase'目錄來測驗):
import React, {useContext, useState, useEffect}. from 'react。
import {auth, storage, db}. from './firebase'。
const AuthContext = React.createContext()。
export function useAuth() {
return useContext(AuthContext)。
}
const initialValue = {
isAuthenticated: false,
user: null, user: null
}
const reducer = (state, action) => {
switch(action.type) {
case 'LOGIN'/span>:
return {
...狀態。
isAuthenticated: true。
user: action.payload.user。
}
case 'LOGOUT'。
return {
...狀態。
isAuthenticated: false,
user: null, user: null
}
case 'SIGNUP'/span>:
//做一些事情。
return: //do something.
//等等。
default:
return 狀態。
}
}
export function AuthProvider({children}){
const [authState, authDispatch] = useReducer(reducer, initialValue)
const [loading, setLoading] = useState(true)。
useEffect(() => {
//I can't test the following
const unsubscribe = auth.onAuthStateChanged((user) => {
db.collection('user')
.doc(user.uid)
.onSnapshot((doc) => {
var data = doc.data()。
authDispatch( {
type: 'LOGIN'。
payload: {
user: data
}
});
});
setLoading(false)。
});
return unsubscribe;
}, []);
return (
<AuthContext. Provider value={{authState, authDispatch}}>/span>
{!加載&&children}{!
</AuthContext.Provider>
);
}
然后當你需要背景關系時:
const MyComponent = (/span>) => {
const {authState, authDispatch} = useAuth();
const handleLogout = (e) => {
authDispatch({
type: e.target.value。
})
}
return (
<div>
我的UID是{authState.user.uid}。< button onClick={handleLogout} value={'LOGOUT'}/>
</div>
);
};
uj5u.com熱心網友回復:
你是否嘗試過在dep陣列中傳遞currentUser
useEffect(() =>/span> {
const unsubscribe = auth.onAuthStateChanged((user) =>/span> {
setCurrentUser(user)。
db.collection('user')
.doc(user.uid)
.onSnapshot((doc) => {
var data = doc.data()。
setCurrentUserData(資料)。
});
setLoading(false)。
});
return unsubscribe;
}, [currentUser])。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/325764.html
標籤:
