Как настроить firebase auth onAuthStateChanged (), слушатель запускается при загрузке приложения React? - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь настроить аутентификатор 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

  },[]);

Ответы [ 2 ]

1 голос
/ 14 июня 2019

Слушатель не является непосредственным.Изменение состояния может занять некоторое время с момента первой загрузки страницы.Если вы хотите немедленно проверить, вошел ли пользователь в систему, вы можете использовать currentUser , но, опять же, обновление может занять некоторое время, поэтому лучшим выбором будет прослушиватель.

1 голос
/ 14 июня 2019

См. https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1

Почему мы вернули функцию из нашего эффекта? Это дополнительный механизм очистки для эффектов. Каждый эффект может возвращать функцию, которая очищается после него. Это позволяет нам поддерживать логику добавления и удаления подписок близко друг к другу. Они являются частью одного и того же эффекта!

Когда именно React очищает эффект? React выполняет очистку при размонтировании компонента. Однако, как мы узнали ранее, эффекты запускаются для каждого рендера, а не только один раз. Вот почему React также очищает эффекты от предыдущего рендера, прежде чем запускать эффекты в следующий раз. Ниже мы обсудим, почему это помогает избежать ошибок и как отказаться от этого поведения в случае, если это создает проблемы с производительностью.

И смотрите Установите наблюдателя состояния аутентификации и получите данные пользователя

Попробуйте следующий код.

function App() {
  console.log('Rendering App...');
  const [authUser,setAuthUser] = useState(null);
  const [authWasListened,setAuthWasListened] = useState(false);

  useEffect(()=>{
    console.log('Running App useEffect...');
    firebase.auth().onAuthStateChanged(
      (authUser) => {

        console.log(authUser);
        console.log(authUser.uid);

        if(authUser) {
          setAuthUser(authUser);
          setAuthWasListened(true);
        } else {
          setAuthUser(null);
          setAuthWasListened(true);
        }

      }
    );
  },[]);

  return(
    authWasListened ?
    <Layout/>
    : <div>Waiting for auth...</div>
  );

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...