【问题标题】:Hide react component until onAuthStateChanged has fired隐藏反应组件,直到 onAuthStateChanged 触发
【发布时间】:2021-10-06 20:41:11
【问题描述】:

我有一个使用 firebase 进行身份验证的简单反应应用程序。使用 firebase 的问题是,我需要等待 onAuthStateChanged 回调触发,然后才能确定用户是否登录,这只需要一秒钟左右。

我想显示该时间段的加载消息,以便当应用程序显示给用户时,我可以确定我们已经确定了用户。触发回调并且我们为用户确定了状态后,加载应用程序。

下面代码的问题在于,loading 的值从 false 更改为 true 的速度似乎比 onAuthStateChanged 回调被触发的速度快,这意味着应用程序的加载速度比我们有确定的状态要快用户。因此,如果有人导航到仪表板,则尽管用户实际已登录,但仍会首先触发登录的重定向。

我真的需要能够设置像displayApp 这样在回调中设置为true 的变量。但是,如果我这样做,我会收到一条错误消息,提示

从 React Hook useEffect 内部对 'displayApp' 变量的分配将在每次渲染后丢失。

这是有道理的,因为每次都会重新渲染组件并且值会丢失。

在这种情况下保持变量的最佳方法是什么,以便我只能在回调触发后显示我的应用程序?

const auth = firebase.auth();
const AuthStateContext = React.createContext(undefined);

function App() {

    const user = useFirebaseAuth();
    const [value, loading] = useAuthState(auth);
    console.log("Loading: ", loading);
    let displayApp = false;

    useEffect(() => {
        firebase.auth().onAuthStateChanged(authUser => {
            console.log("Auth user:", authUser);
            console.log("Loading (auth): ", loading);
            displayApp = true;
        })
    })

    return (
        <>
            {!loading &&
            <Switch>
                <Route path="/" exact>
                    {user ? <Dashboard/> : <Login/> }
                </Route>
                <Route path="/dashboard">
                    <Dashboard/>
                </Route>
                <Route path="/login">
                    <Login/>
                </Route>
            </Switch>
            }
            {loading &&
            <h4>Loading...</h4>
            }
        </>

    )
}
export default function Dashboard(props){
    const auth = firebase.auth();
    const user = useFirebaseAuth();

    console.log("Dashboard");
    if(!user){
        return (
            // <h4>Not logged</h4>
            <Redirect to="/login"/> //Since the app is loaded before the user is retrieved, this gets triggered despite the user being logged in 
        )
    }

    return (
        <>
            <h1>Dashboard</h1>
            <h4>{auth.currentUser?.displayName}</h4>
            <button onClick={() => firebase.auth().signOut()}>Sign out</button>
        </>
    )
}

【问题讨论】:

  • 不要持久化到变量中。这就是错误消息试图告诉您的内容。相反,坚持一些共享状态(可能是 redux 存储),当更新时,会导致组件重新渲染。
  • @DougStevenson 我还在学习反应,所以还没有使用 redux。但是我已经设法通过使用 chrome 本地存储来完成该行为。我假设 redux 可以同步检索?

标签: reactjs firebase firebase-authentication


【解决方案1】:

在 react hooks 中,给变量赋值的最好方法是使用 useState

import {useState} from "react"; //Add this import
const auth = firebase.auth();
const AuthStateContext = React.createContext(undefined);

function App() {

    const user = useFirebaseAuth();
    const [value, loading] = useAuthState(auth);
    console.log("Loading: ", loading);
    const [displayApp, setDisplayApp] = useState(false); //change the initialization of the variable 

    useEffect(() => {
        firebase.auth().onAuthStateChanged(authUser => {
            console.log("Auth user:", authUser);
            console.log("Loading (auth): ", loading);
            setDisplay(true); //Set the value that you want
        })
    })

这可以防止“displayApp”变量在每次渲染中重置

【讨论】:

    猜你喜欢
    • 2021-05-10
    • 1970-01-01
    • 2018-09-27
    • 2021-10-30
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    相关资源
    最近更新 更多