Я пытаюсь настроить аутентификатор Firebase на моем компоненте верхнего уровня App
, чтобы предоставить объект authUser
через контекст React всем другим компонентам.
Я сейчас делаю это:
function App() {
console.log('Rendering App...');
const [authUser,setAuthUser] = useState(null);
const [authWasListened,setAuthWasListened] = useState(false);
useEffect(()=>{
console.log('Running App useEffect...');
const authListener = firebase.auth().onAuthStateChanged(
(authUser) => {
console.log(authUser);
console.log(authUser.uid);
if(authUser) {
setAuthUser(authUser);
setAuthWasListened(true);
} else {
setAuthUser(null);
setAuthWasListened(true);
}
}
);
return authListener();
},[]);
return(
authWasListened ?
<Layout/>
: <div>Waiting for auth...</div>
);
}
Но я получаю вывод журнала:
Rendering App...
Running App useEffect...
Кажется, я настраиваю прослушиватель, но сначала он не запускается, поэтому он не получает текущее состояние аутентификации (что является нулевым, поскольку у меня даже нет формы входа). Похоже, что он ждет изменений.
Разве authListener
не должен сначала получить текущее состояние authUser
, а затем прослушивать изменения? Что я делаю не так?
UPDATE
Я узнал, что я делал неправильно. useEffect
должен возвращать функцию для очистки слушателя на unmount
, а не вызов функции, как я пытался сделать выше. Так что мой слушатель никогда не настраивался.
Это работает, как задумано:
useEffect(()=>{
console.log('Running App useEffect...');
const authListener = firebase.auth().onAuthStateChanged(
(authUser) => {
console.log(authUser);
console.log(authUser.uid);
if(authUser) {
setAuthUser(authUser);
setAuthWasListened(true);
} else {
setAuthUser(null);
setAuthWasListened(true);
}
}
);
return () => authListener(); // THIS MUST BE A FUNCTION, AND NOT A FUNCTION CALL
},[]);