首页 > 解决方案 > 登录时的每次页面刷新都会让我回到仪表板(使用受保护路由的持久登录)

问题描述

我已经实现了一个简单protected route的 from Login& other protected components

受保护的路线Login.js

import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'

const ProtectedRoute\Login = ({ component: Component, ...rest }) => {
  const [authState, authDispatch] = useAuth()
  const { authenticated, loading } = authState

  // check if user is authenticated
  useEffect(() => {
    (async() => {
      await isAuthenticated(authDispatch)
      setLoading(authDispatch, false)
    })();
  }, [])

  return (
    <Route
      {...rest} render={
        props => {
          if(loading) return <div className="lds-hourglass"></div>
          if(!authenticated) return <Component {...props} />
          else return <Redirect exact to={{
            // here I redirect logged-in user to dashboard
            pathname: "/dashboard",
            state: { from: props.location }
          }} />
        }
      } 
    />
  )
}

export default ProtectedRouteLogin

受保护的路由Dashboard.js或其他受保护的组件

import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'

const ProtectedRouteOthers = ({ component: Component, ...rest }) => {
  const [authState, authDispatch] = useAuth()
  const { authenticated, loading } = authState

  // check if user is authenticated
  useEffect(() => {
    (async() => {
      await isAuthenticated(authDispatch)
      setLoading(authDispatch, false)
    })();
  }, [])

  return (
    <Route 
      {...rest} render={
        props => {
          if(loading) return <div className="lds-hourglass"></div>
          if(authenticated) return <Component {...props} />
          else return <Redirect to={
            {
              // here redirect NOT logged-in user back to login page
              pathname: "/login",
              state: { from: props.location }
            }
          } />
        }
      } 
    />
  )
}

export default ProtectedRouteOthers

面临的问题

export const isAuthenticated = async(dispatch) => {
  setLoading(dispatch, true)

  // get user cookie
  let userExist = getCookie('user')

  /** Cookie Checking Style */
  if(userExist) {
    dispatch({
      type: 'SET_ISAUTHENTICATED',
      payload: true
    })
  } else {
    dispatch({
      type: 'SET_ISAUTHENTICATED',
      payload: false
    })
  }
}

那么如何更改我的代码,以便每次刷新保护的页面时(登录时)。我会留在刷新的页面上,而不是回到Dashboard页面上吗?

标签: reactjspersistencereact-router-dom

解决方案


幸运的是,我找到了解决方案。但我不知道这是否是一个可接受的解决方案。至少这种逻辑对于克服我的问题是有意义的。

我决定在渲染页面和其他受保护的页面之前添加一个逻辑(在&中添加了逻辑)Login.js componentsProtected Route componentsProtectedRouteLogin.jsProtectedRouteOthers

添加的逻辑ProtectedRouteLogin.js

  • 在渲染到Dashboard.js页面之前,如果用户已通过身份验证,我会检查是否已props.location.pathname 保存。如果存在/存在,那么就说。否则,只是页面cookie renderpathnamerenderDashboard.js
  • ProtectedRouteLogin.js:-
import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'
import { getCookie } from '../../../services/Cookie'

const ProtectedRouteLogin = ({ component: Component, ...rest }) => {
  const [authState, authDispatch] = useAuth()
  const { authenticated, loading } = authState

  // check if user is authenticated
  useEffect(() => {
    (async() => {
      await isAuthenticated(authDispatch)
      setLoading(authDispatch, false)
    })();
  }, [])

  return (
    <Route
      {...rest} render={
        props => {
          if(loading) return <div className="lds-hourglass"></div>
          if(!authenticated) return <Component {...props} />
          else {
            // get pathname save in cookie
            let url = getCookie('onRefresh')
            
            return <Redirect exact to={{
              // ternary function to determine redirection
              pathname: url !== '' ? url : '/pfv4-admin/dashboard',
              state: { from: props.location }
            }} />
          }
        }
      } 
    />
  )
}

export default ProtectedRouteLogin

添加的逻辑ProtectedRouteOthers.js

  • 在这里,在渲染到任何受保护 components的之前,我将其设置为 保存即将访问的或url。所以,我可以在上面交叉检查这个url 。cookieprops.location.pathnamecomponentProtectedRouteLogin.js
  • ProtectedRouteOthers.js:-
import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'
import { setCookie } from '../../../services/Cookie'

const ProtectedRouteOthers = ({ component: Component, ...rest }) => {
  const [authState, authDispatch] = useAuth()
  const { authenticated, loading } = authState

  // check if user is authenticated
  useEffect(() => {
    (async() => {
      await isAuthenticated(authDispatch)
      setLoading(authDispatch, false)
    })();
  }, [])

  return (
    <Route 
      {...rest} render={
        props => {
          if(loading) return <div className="lds-hourglass"></div>
          if(authenticated) {
            // save last page seen address (url)
            setCookie('onRefresh', props.location.pathname, { path: '/' }) 
            return <Component {...props} />
          }
          else return <Redirect to={
            {
              pathname: "/pfv4-admin",
              state: { from: props.location }
            }
          } />
        }
      } 
    />
  )
}

export default ProtectedRouteOthers

随意为这个问题添加你自己可能的解决方案。期待尝试它们。


推荐阅读