受保护的路由器在 Redux 状态更新时不会重新渲染
Protected router doesn't re-render when Redux state update
我正在尝试使用受保护的路由来防止未经身份验证的用户看到页面。为此,每次重新加载页面时,我都会连接到服务器以检查令牌并查看用户是否已通过身份验证,并根据服务器响应更新 Redux 状态。这工作正常,但是当我尝试更新受保护的路由组件时出现问题。由于服务器响应延迟,组件第一次渲染默认状态值为 false
,但是当我获得服务器响应并将 Redux 状态更新为 true
时,我的组件不会重新渲染 [=13] =]
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)
也许您可以使用如下所示的“browserHistory”进行重定向。
import { browserHistory } from 'react-router'
// ...
else {
console.log('protected else')
return browserHistory.push('/forbidden');
}
我也有类似的问题。
首先,您需要派发一个操作来检查用户是否在您的商店呈现后立即通过身份验证。
由于身份验证似乎是一个异步过程,您可能希望发送两个操作:auth_verification_request
商店首次呈现时,以及 auth_verification_success
身份验证成功时。
然后更新的状态将使用 mapStateToProps
函数发送到您的 ProtectedRoute
。之后,您的组件应该 re-render 在身份验证状态更新后。
我给你举几个例子。
authActions.js
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
应该看起来像这样:
ProtectedRoute.js
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
变量传递给您的 ProtectedRoute
。像这样:
Router.js
const mapStateToProps = state => {
return {
isAuthenticated: state.auth.isAuthenticated,
isVerifying: state.auth.isVerifying,
};
}
<PrivateRoute
exact
path='PROTECTED_PATH'
component={ DashboardPage }
isAuthenticated={ isAuthenticated }
isVerifying={ isVerifying }
/>
如果您对我的代码有任何疑问,请告诉我。
根据 ,解决方案是向组件添加 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)
我不确定这是处理这个问题的最佳方法,但它似乎解决了我的头痛。
我正在尝试使用受保护的路由来防止未经身份验证的用户看到页面。为此,每次重新加载页面时,我都会连接到服务器以检查令牌并查看用户是否已通过身份验证,并根据服务器响应更新 Redux 状态。这工作正常,但是当我尝试更新受保护的路由组件时出现问题。由于服务器响应延迟,组件第一次渲染默认状态值为 false
,但是当我获得服务器响应并将 Redux 状态更新为 true
时,我的组件不会重新渲染 [=13] =]
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)
也许您可以使用如下所示的“browserHistory”进行重定向。
import { browserHistory } from 'react-router'
// ...
else {
console.log('protected else')
return browserHistory.push('/forbidden');
}
我也有类似的问题。
首先,您需要派发一个操作来检查用户是否在您的商店呈现后立即通过身份验证。
由于身份验证似乎是一个异步过程,您可能希望发送两个操作:auth_verification_request
商店首次呈现时,以及 auth_verification_success
身份验证成功时。
然后更新的状态将使用 mapStateToProps
函数发送到您的 ProtectedRoute
。之后,您的组件应该 re-render 在身份验证状态更新后。
我给你举几个例子。
authActions.js
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
应该看起来像这样:
ProtectedRoute.js
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
变量传递给您的 ProtectedRoute
。像这样:
Router.js
const mapStateToProps = state => {
return {
isAuthenticated: state.auth.isAuthenticated,
isVerifying: state.auth.isVerifying,
};
}
<PrivateRoute
exact
path='PROTECTED_PATH'
component={ DashboardPage }
isAuthenticated={ isAuthenticated }
isVerifying={ isVerifying }
/>
如果您对我的代码有任何疑问,请告诉我。
根据 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)
我不确定这是处理这个问题的最佳方法,但它似乎解决了我的头痛。