React身份验证上下文最初为空 [英] React Authentication Context being null initially

查看:61
本文介绍了React身份验证上下文最初为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用React上下文来保留我的应用程序的身份验证状态.当前,我遇到一个问题,即每当我尝试按/groups/:id时,它总是首先将我重定向到/login,然后再重定向到/UserDash.发生这种情况是因为AuthProvider的上下文更新速度不够快,并且我的私有路由利用AuthContext来决定是否重定向.

I'm using React contexts in order to hold my authentication state for my application. Currently, I'm having an issue where whenever I try and hit /groups/:id, it always redirects me to /login first and then to /UserDash. This is happening because the context of my AuthProvider isn't updating fast enough, and my Private Route utilized the AuthContext to decide whether to redirect or not.

<AuthProvider>
    <Router>
        <Switch>
            <LoggedRoute exact path = "/" component = {Home}/>
            <Route exact path = "/login" component = {Login}/>
            <PrivateRoute exact path = "/groups/:id" component = {GroupDash}/>
            <PrivateRoute exact path = "/UserDash" component = {UserDash}/>
        </Switch>
    </Router>
</AuthProvider>

在另一个文件中:

export const AuthContext = React.createContext();

export const AuthProvider = ({children}) => {
  const [currentUser, setCurrentUser] = useState(null);
  useEffect(() => {
      firebaseApp.auth().onAuthStateChanged(setCurrentUser);
  },[]);
    return (
        <AuthContext.Provider
            value = {{currentUser}}
        >
            {children}
        </AuthContext.Provider>
    );

我的私人路线:

const PrivateRoute = ({component: RouteComponent, ...rest}) => {
    const {currentUser} = useContext((context) => AuthContext);
    return (
        <Route
            {...rest}
            render={routeProps => (currentUser) ? (<RouteComponent{...routeProps}/>) : (<Redirect to={"/login"}/>)}
        />
    )
};

还有我的登录页面

 const {currentUser} = useContext(AuthContext);
    if (currentUser) {
        return <Redirect to = "/UserDash" />
    }
    return (
        <button onClick={(e) => {googleLogin(history)}}>Log In</button>
    );

在私有路由将用户重定向到登录页面之前,是否有任何方法可以强制加载上下文?我尝试在PrivateRoute内使用firebase.auth().currentUser,但这也失败了,在被推送到"/UserDash"之前,我仍然被重定向到"/login".

Is there any way to force the context to load before the private route redirects the user to the login page? I've tried using firebase.auth().currentUser inside my PrivateRoute instead, but that also fails and I still get redirected to "/login", before getting pushed to "/UserDash".

推荐答案

由于useEffect在渲染后运行,并且useEffect中获取的值来自异步调用,所以实际上可以保持加载状态,直到有可用数据为止.

Since useEffect runs after a render and the value being fetched in useEffect is from a async call what can do is to actually maintain a loading state till data is available like

export const AuthContext = React.createContext();

export const AuthProvider = ({children}) => {
  const [currentUser, setCurrentUser] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  useEffect(() => {
      firebaseApp.auth().onAuthStateChanged((user) => {
          setCurrentUser(); setIsLoading(false)
      });
  },[]);
    return (
        <AuthContext.Provider
            value = {{currentUser, isLoading}}
        >
            {children}
        </AuthContext.Provider>
    );
  }


然后在privateRoute中


Then in privateRoute

const PrivateRoute = ({component: RouteComponent, ...rest}) => {
    const {currentUser, isLoading} = useContext((context) => AuthContext);
    if(isLoading) return <div>Loading...</div>
    return (
        <Route
            {...rest}
            render={routeProps => (currentUser) ? (<RouteComponent{...routeProps}/>) : (<Redirect to={"/login"}/>)}
        />
    )
};

这篇关于React身份验证上下文最初为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆