我正在尝试使用受保护的路由来防止未经身份验证的用户看到页面。为此,每次页面重新加载时,我都会连接到服务器以检查令牌,并查看是否经过了用户身份验证,并在服务器响应时更新了Redux状态。这可以正常工作,但是当我尝试更新“受保护的路由”组件时出现了问题。由于服务器响应的延迟,组件第一次使用默认状态值false
进行渲染,但是当我获得服务器响应并将Redux状态更新为true
时,组件不会重新渲染
function ProtectedRoute(props, {component: Component, ...rest}){
return (
<Route
{...rest}
render={props =>{
if(props.userLoginStatus){
console.log('protected if')
return <Component {...props} />
} else {
console.log('protected else')
return <Redirect to={{
pathname: '/forbidden',
state: {from: props.location}
}}
/>
}
}}
/>
)
}
const mapStateToProps = (state) => {
return {
userLoginStatus: state.userLoginReducer.userLogin
}
}
export default connect(mapStateToProps)(ProtectedRoute)
答案 0 :(得分:0)
也许您可以使用以下“ browserHistory”进行重定向。
import { browserHistory } from 'react-router'
// ...
else {
console.log('protected else')
return browserHistory.push('/forbidden');
}
答案 1 :(得分:0)
我也有类似的问题。
首先,您需要调度一个操作,以检查在呈现商店之后用户是否已通过身份验证。
由于身份验证验证似乎是一个异步过程,因此您可能要发送两个操作:import React, {useEffect} from 'react'
import CircleType from 'circletype'
function RotatingCircle() {
// const circleOfSkills = new CircleType(document.getElementById('rounded-text'))
// .radius(100)
// useEffect(() => {
// return () => circleOfSkills.mount()
// }, [circleOfSkills])
return (
<p className="circle" id="rounded-text">
AND THE WORLD KEEPS GOING AROUND AND AROUND AND AROUND
</p>
)
}
export default RotatingCircle
(在商店首先呈现时)和auth_verification_request
(在成功验证身份时)。
然后,将使用auth_verification_success
函数将更新后的状态发送到您的ProtectedRoute
。之后,您的组件应在身份验证状态更新后重新呈现。
我将向您展示一些示例。
authActions.js
mapStateToProps
您的export const verifyAuth = () => {
return ((dispatch) => {
// auth verification requested
dispatch({
type: 'VERIFY_REQUEST'
})
// signin request
dispatch({
type: 'SIGN_IN_REQUEST'
});
// check if user is logged in or not
if (logged_in) {
// signin success
dispatch({
type: 'SIGN_IN_SUCCESS'
})
// auth verification success
dispatch({
type: 'VERIFY_SUCCESS'
})
}
// if not logged in
else {
// auth verification rejected
dispatch({
type: 'VERIFY_ERROR'
})
}
}
}
应该看起来像这样:
ProtectedRoute.js
ProtectedRoute
当您使用这些组件时,请确保将const ProtectedRoute = ({
component: Component,
isAuthenticated,
isVerifying,
...rest
}) => {
return (
<Route { ...rest }
render={ props =>
isVerifying ? (
<div />
) : isAuthenticated ? (
<Component { ...props } />
) : (
<Redirect
to={ {
pathname: 'REDIRECT_PATH',
state: { from: props.location }
} }
/>
)
}
/>
)
};
和isAuthenticated
变量传递给isVerifying
。像这样:
Router.js
ProtectedRoute
如果您对我的代码有疑问,请告诉我。
答案 2 :(得分:0)
根据this post,解决方案是向组件添加if
语句,以渲染加载,直到组件从服务器得到答案为止。因此,我将默认操作值从false
更改为null
并添加了if
语句。在我的代码中,它看起来像这样:
function ProtectedRoute({component: Component, isAuth, ...rest}){
//Whaiting until gets response from server
if (isAuth === null) {
return 'loading..'
}
return (
<Route
{...rest}
render={(props) => {
if(isAuth){
console.log('protected if')
return <Component {...props} />
} else {
return <Redirect to={{
pathname: '/forbidden',
state: {from: props.location}
}}
/>
}
}}
/>
)
}
const mapStateToProps = (state) => {
return {
isAuth: state.userLoginReducer.userLogin
}
}
export default connect(mapStateToProps)(ProtectedRoute)
我不确定是解决这个问题的最佳方法,但似乎可以解决我的头痛。