Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 应用程序刷新时onAuthStateChanged Firebase侦听器导致私有路由问题_Javascript_Reactjs_Firebase_Firebase Authentication - Fatal编程技术网

Javascript 应用程序刷新时onAuthStateChanged Firebase侦听器导致私有路由问题

Javascript 应用程序刷新时onAuthStateChanged Firebase侦听器导致私有路由问题,javascript,reactjs,firebase,firebase-authentication,Javascript,Reactjs,Firebase,Firebase Authentication,我目前已使用firebase初始化了React应用程序。在应用程序中,我使用react router dom创建了一个开放的登录路由和一个私有的家庭路由。我的app.js看起来是这样的: import React, { useContext } from 'react' import { Route, Redirect } from 'react-router-dom' import { AppContext } from '../context/AppContext' const Priva

我目前已使用firebase初始化了React应用程序。在应用程序中,我使用react router dom创建了一个开放的登录路由和一个私有的家庭路由。我的app.js看起来是这样的:

import React, { useContext } from 'react'
import { Route, Redirect } from 'react-router-dom'
import { AppContext } from '../context/AppContext'

const PrivateRoute = ({ component: Component, ...rest }) => {
  const { currentUser } = useContext(AppContext)
  return (
    <Route
      {...rest}
      render={routeProps =>
        !!currentUser ? (
          <Component {...routeProps} />
        ) : (
          <Redirect to={'/login'} />
        )
      }
    />
  )
}

export default PrivateRoute
App.js:

import React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import Login from './pages/Login'
import Home from './pages/Home'
import PrivateRoute from './utils/PrivateRoute'

const App = () => {
  return (
    <BrowserRouter>
      <Switch>
        <PrivateRoute exact path='/' component={Home} />
        <Route path='/login' component={Login} />
      </Switch>
    </BrowserRouter>
  )
}

export default App
从“React”导入React
从“react router dom”导入{BrowserRouter,Switch,Route}
从“./pages/Login”导入登录名
从“./pages/Home”导入主页
从“/utils/PrivateRoute”导入PrivateRoute
常量应用=()=>{
返回(
)
}
导出默认应用程序
我使用onAuthStateChanged firebase事件侦听器将currentUser存储在上下文中,如下所示:

AppContext:

import { useEffect, useState, createContext } from 'react'
import { auth } from '../utils/firebase'

export const AppContext = createContext()

export const AppProvider = ({ children }) => {
  const [currentUser, setCurrentUser] = useState(null)

  useEffect(() => {
    auth.onAuthStateChanged(setCurrentUser)
  }, [])

  return (
    <AppContext.Provider value={{ currentUser }}>
      {children}
    </AppContext.Provider>
  )
}
从'react'导入{useffect,useState,createContext}
从“../utils/firebase”导入{auth}
export const AppContext=createContext()
export const AppProvider=({children})=>{
常量[currentUser,setCurrentUser]=useState(null)
useffect(()=>{
auth.onAuthStateChanged(setCurrentUser)
}, [])
返回(
{儿童}
)
}
当用户通过登录路径登录时:

登录:

import React, { useState, useCallback, useContext } from 'react'
import { auth } from '../utils/firebase'
import { useHistory, Redirect } from 'react-router-dom'


function Login() {
  const [formData, setFormData] = useState({ email: '', password: '' })
  const history = useHistory()

  const handleChange = ({ target: { name, value } }) => {
    setFormData({ ...formData, [name]: value })
  }

  const handleSubmit = useCallback(
    async event => {
      event.preventDefault()
      await auth
        .createUserWithEmailAndPassword(formData.email, formData.password)
        .then(user => {
          console.log(user)
          history.push('/')
        })
        .catch(err => {
          alert(err)
        })
    },
    [history, formData.email, formData.password]
  )

  return (
    <div className='form-container sign-up-container'>
      <form className='register-form' onSubmit={handleSubmit}>
        <h1>Create Account</h1>
        <div className='social-container'>
          <div className='social'>
            <i className='fab fa-facebook-f'></i>
          </div>
          <div className='social'>
            <i className='fab fa-google-plus-g'></i>
          </div>
          <div className='social'>
            <i className='fab fa-linkedin-in'></i>
          </div>
        </div>
        <span>or use your email for registration</span>

        <input
          type='email'
          placeholder='Email'
          name='email'
          onChange={handleChange}
        />

        <input
          type='password'
          placeholder='Password'
          name='password'
          onChange={handleChange}
        />

        <button type='submit'>Sign Up</button>
      </form>
    </div>
  )
}

export default Login
import React,{useState,useCallback,useContext}来自“React”
从“../utils/firebase”导入{auth}
从“react router dom”导入{useHistory,Redirect}
函数登录(){
const[formData,setFormData]=useState({电子邮件:'',密码:'})
const history=useHistory()
const handleChange=({target:{name,value}})=>{
setFormData({…formData,[名称]:值})
}
const handleSubmit=useCallback(
异步事件=>{
event.preventDefault()
等待授权
.createUserWithEmailAndPassword(formData.email,formData.password)
。然后(用户=>{
console.log(用户)
history.push(“/”)
})
.catch(错误=>{
警报(错误)
})
},
[历史记录,formData.email,formData.password]
)
返回(
创建帐户
或者使用您的电子邮件进行注册
注册
)
}
导出默认登录名
当前用户成功地存储在上下文中,用户被推送到私有主路由中

专用路线如下所示:

import React, { useContext } from 'react'
import { Route, Redirect } from 'react-router-dom'
import { AppContext } from '../context/AppContext'

const PrivateRoute = ({ component: Component, ...rest }) => {
  const { currentUser } = useContext(AppContext)
  return (
    <Route
      {...rest}
      render={routeProps =>
        !!currentUser ? (
          <Component {...routeProps} />
        ) : (
          <Redirect to={'/login'} />
        )
      }
    />
  )
}

export default PrivateRoute
import React,{useContext}来自“React”
从“react router dom”导入{Route,Redirect}
从“../context/AppContext”导入{AppContext}
const privaterout=({component:component,…rest})=>{
const{currentUser}=useContext(AppContext)
返回(
!!当前用户(
) : (
)
}
/>
)
}
导出默认PrivateRoute

我遇到的问题是,当应用程序刷新时,currentUser最初变为null,然后currentUser的信息重新加载。当刷新时currentUser为null时,用户将从主路由踢出并重定向到登录页面。我想知道是否有人对如何防止这种情况发生有任何建议。

您使用空值初始化
currentUser
状态变量:

const [currentUser, setCurrentUser] = useState(null)
这意味着当第一次加载页面时,
currentUser
最初总是空的。在Firebase SDK异步加载之前,之前的用户对象直到一段时间后才能确定。您的代码需要为此做好准备。如果在呈现组件之前要求用户登录,则应等待第一次使用实际用户对象触发
onAuthStateChanged

您可以在中阅读有关Firebase Auth SDK此行为的更多信息