Мгновенно реагировать на состояние обновления API - PullRequest
2 голосов
/ 19 апреля 2020

Я использую контекстный API в настройке Gatsby, чтобы отслеживать состояние с именем userIsLoggedIn. Я использую Firebase для аутентификации.

Это мой контекстный файл:

import { createContext } from "react"

export const AppContext = createContext(null)

Это мой компонент AppWrapper:

import React, { useState, useEffect } from "react"
import firebase from "../../config/firebase"
import { AppContext } from "../../context/AppContext"

const AppWrapper = ({ children }: any) => {
  const [userIsLoggedIn, setUserIsLoggedIn] = useState(false)

  const authListener = () => {
    firebase.auth().onAuthStateChanged(user => {
      if (user && user.emailVerified) {
        setUserIsLoggedIn(true)
      } else {
        setUserIsLoggedIn(false)
      }
    })
  }

  useEffect(() => {
    authListener()
  }, [])

  return (
    <>
      <AppContext.Provider
        value={{
          userIsLoggedIn,
        }}
      >
        <main>{children}</main>
      </AppContext.Provider>
    </>
  )
}

export default AppWrapper

Это моя страница индекса, где Я хочу отслеживать, вошел ли пользователь в систему, чтобы я мог показать / скрыть определенное содержимое:

import React, { useContext } from "react"
import { AppContext } from "../context/AppContext"

const IndexPage = () => {
  const app = useContext(AppContext)

  console.log("app", app)

  return (
    <>
      {app && app.userIsLoggedIn && (
        <>
          <h1>Hello dearest user</h1>
          <p>Welcome to your page.</p>
        </>
      )}
    </>
  )
}

export default IndexPage

Результатом работы моего console.log в компоненте my IndexPage при первой загрузке является следующее. страница или всякий раз, когда страница перезагружается:

app {userIsLoggedIn: false}
app {userIsLoggedIn: true}

Это означает, что моя страница перерисовывается и мой контент мерцает между контентом, который скрыт / отображается, когда пользователь вошел в систему. Есть ли способ избежать этого и сделать государство более мгновенным? Я открыт для любых предложений:)

1 Ответ

0 голосов
/ 19 апреля 2020

Хорошо, я выяснил, что помогает моему конкретному делу. Вместо использования контекста api для сохранения состояния приложения (которое будет перезагружено до значения по умолчанию при перезагрузке, а следовательно, и мерцания между состояниями), я использую localStorage для сохранения, если пользователь вошел в систему в сочетании с моей функцией authListener.

Это auth util Я добавил:

// Firebase
import firebase from "../config/firebase"

export const isBrowser = () => typeof window !== "undefined"

export const getUser = () => {
  if (isBrowser()) {
    const user = window.localStorage.getItem("user")
    if (user !== null) {
      return JSON.parse(user)
    } else {
      return ""
    }
  }
}

export const setUser = (email: string | null) =>
  isBrowser() && window.localStorage.setItem("user", JSON.stringify(email))

export const isLoggedIn = () => {
  const user = getUser()
  return !!user
}

export const logout = () => {
  return new Promise(resolve => {
    firebase
      .auth()
      .signOut()
      .then(() => {
        setUser("")
        resolve()
      })
  })
}

и внутри моей AppWrapper моя authListener функция теперь выглядит так:

import { setUser, logout } from "../../utils/auth"

const authListener = () => {
    firebase.auth().onAuthStateChanged(user => {
      if (user && user.emailVerified) {
        setUser(user.email)
      } else {
        logout()
      }
    })
  }

  useEffect(() => {
    authListener()
  })

В любом месте в В моем приложении я могу использовать утилиту isLoggedIn(), чтобы проверить, действительно ли пользователь вошел в систему без мерцающего содержимого.

Если я вручную удаляю или изменяю localStorage user, это будет немедленно обновлено authListener функция, когда что-то меняется в приложении.

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