刷新后反应 Redux 和状态
React Redux and state after refresh
我无法理解为什么我的应用运行起来有点奇怪。当我尝试通过单击导航栏中的 link 按钮访问我页面上的任何站点时,它会毫无问题地导航到那里,就像当我单击“我的帐户”时,URL 更改为“http: //localhost:3000/my_account”,一切正常。在这个地方我不得不提到“/my_account”是一个受保护的路由——用户必须登录才能访问它,当他没有登录时——他会被发送到主页。所以现在的问题是,当用户登录并尝试通过输入此 URL 并加载页面来访问“http://localhost:3000/my_account”之类的受保护路由时 - 他被视为一个未登录的用户并被重定向到主页。在他被重定向到那里并尝试通过单击导航栏 link 访问此站点后,他可以进入此页面 - 他已登录。我的预期结果是用户可以在站点上输入任何 URL如果他在两种情况下都已登录,则 React 应该正确检查他是否已登录 - 无论是在网站上单击 link 还是通过提供 url。谁能告诉我哪里出错了?
UserAccount (/my_account) 是一个简单的组件:
import React, { Component } from 'react'
export class UserAccount extends Component {
render() {
return (
<div>
UserAccount
</div>
)
}
}
export default UserAccount
在 App.js 的路由器中,我将此路由声明为:
<PrivateRoute path="/my_account" exact component={UserAccount}></PrivateRoute>
而 PrivateRoute 是一个功能组件:
import React from 'react'
import {Route, Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
const PrivateRoute = ({component : Component, auth, ...rest}) => (
<Route {...rest} render={props => {
if(auth.isLoading){
return <h2>LOADING ...</h2>
}
else if(!auth.isAuthenticated){
return <Redirect to="/login"></Redirect>
}
else{
return <Component {...props}/>
}
}}></Route>
)
const mapStateToProps = state =>({
auth: state.auth
})
export default connect(mapStateToProps,null)(PrivateRoute);
我在auth.js(reducer)中的状态:
const initialState = {
access: localStorage.getItem('access'),
refresh: localStorage.getItem('refresh'),
isAuthenticated: null,
isLoading : false,
user: null,
requestSent: false,
payload: null,
message: null
}
并且登录成功后,状态变化如下:
switch(type){
case AUTHENTICATED_SUCCESS:
return {
...state,
isAuthenticated: true
}
case LOGIN_SUCCESS:
localStorage.setItem('access', payload.access);
return{
...state,
isAuthenticated: true,
access: payload.access,
refresh: payload.refresh
}
以及来自 auth.js 操作的登录功能:
export const login = (email, password) => async dispatch =>{
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({email, password});
try{
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/jwt/create/`, body, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
})
dispatch(load_user());
dispatch(createMessage({logged_in_successfully: "You are now logged in."}))
} catch (err) {
dispatch({
type: LOGIN_FAIL,
payload: err
})
const errors = {msg: err.response.data, status: err.response.status}
dispatch({
type:GET_ERRORS,
payload: errors
})
}
};
感谢您花时间阅读这篇文章,我希望能得到一些帮助。
import React, { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
export default function UserAccount() {
let navigate = useNavigate();
useEffect(() => {
let authToken = sessionStorage.getItem('access')
// if user is not authed, redirect user to login page
if (!authToken) {
navigate('/login')
}
}, [])
return (
<div>
Home Page
</div>
)
}
答案使用功能组件和 React 路由器 v6+。如果您提供您使用的 react-router 版本,我可以更新我的答案
您忘记添加检查天气用户是否已授权的条件。为此,您需要检查 UserAccount 页面。我提供了片段。条件应该写在功能组件的 useEffect
里面。 componentDidMount
内基于 class 的组件。可以找到有关身份验证的更多信息
here
除此之外,您还应该在 Login
页面和 Register
页面内添加条件。为了防止用户重新注册和重新登录。
好吧,我可能找到了解决方案。由于我在商店中将空值设置为默认值,因此我更改了我的 PrivateRoute 代码以检查它是否为空,如果是,我们等待渲染或重定向,直到它变为真或假:
import React from 'react'
import {Route, Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
const PrivateRoute = ({component : Component, auth, ...rest}) => (
<Route {...rest} render={props => {
if(auth.isLoading){
return <h2>LOADING ...</h2>
}
else if(auth.isAuthenticated==null){
return <h2>LOADING ...</h2>
}
else if(auth.isAuthenticated==false){
return <h2>Not authenticated ... redirecting here</h2>
}
else{
return <Component {...props}/>
}
}}></Route>
)
const mapStateToProps = state =>({
auth: state.auth,
})
export default connect(mapStateToProps,null)(PrivateRoute);
谁能告诉我这是好主意还是坏主意?
我无法理解为什么我的应用运行起来有点奇怪。当我尝试通过单击导航栏中的 link 按钮访问我页面上的任何站点时,它会毫无问题地导航到那里,就像当我单击“我的帐户”时,URL 更改为“http: //localhost:3000/my_account”,一切正常。在这个地方我不得不提到“/my_account”是一个受保护的路由——用户必须登录才能访问它,当他没有登录时——他会被发送到主页。所以现在的问题是,当用户登录并尝试通过输入此 URL 并加载页面来访问“http://localhost:3000/my_account”之类的受保护路由时 - 他被视为一个未登录的用户并被重定向到主页。在他被重定向到那里并尝试通过单击导航栏 link 访问此站点后,他可以进入此页面 - 他已登录。我的预期结果是用户可以在站点上输入任何 URL如果他在两种情况下都已登录,则 React 应该正确检查他是否已登录 - 无论是在网站上单击 link 还是通过提供 url。谁能告诉我哪里出错了?
UserAccount (/my_account) 是一个简单的组件:
import React, { Component } from 'react'
export class UserAccount extends Component {
render() {
return (
<div>
UserAccount
</div>
)
}
}
export default UserAccount
在 App.js 的路由器中,我将此路由声明为:
<PrivateRoute path="/my_account" exact component={UserAccount}></PrivateRoute>
而 PrivateRoute 是一个功能组件:
import React from 'react'
import {Route, Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
const PrivateRoute = ({component : Component, auth, ...rest}) => (
<Route {...rest} render={props => {
if(auth.isLoading){
return <h2>LOADING ...</h2>
}
else if(!auth.isAuthenticated){
return <Redirect to="/login"></Redirect>
}
else{
return <Component {...props}/>
}
}}></Route>
)
const mapStateToProps = state =>({
auth: state.auth
})
export default connect(mapStateToProps,null)(PrivateRoute);
我在auth.js(reducer)中的状态:
const initialState = {
access: localStorage.getItem('access'),
refresh: localStorage.getItem('refresh'),
isAuthenticated: null,
isLoading : false,
user: null,
requestSent: false,
payload: null,
message: null
}
并且登录成功后,状态变化如下:
switch(type){
case AUTHENTICATED_SUCCESS:
return {
...state,
isAuthenticated: true
}
case LOGIN_SUCCESS:
localStorage.setItem('access', payload.access);
return{
...state,
isAuthenticated: true,
access: payload.access,
refresh: payload.refresh
}
以及来自 auth.js 操作的登录功能:
export const login = (email, password) => async dispatch =>{
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const body = JSON.stringify({email, password});
try{
const res = await axios.post(`${process.env.REACT_APP_API_URL}/auth/jwt/create/`, body, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data
})
dispatch(load_user());
dispatch(createMessage({logged_in_successfully: "You are now logged in."}))
} catch (err) {
dispatch({
type: LOGIN_FAIL,
payload: err
})
const errors = {msg: err.response.data, status: err.response.status}
dispatch({
type:GET_ERRORS,
payload: errors
})
}
};
感谢您花时间阅读这篇文章,我希望能得到一些帮助。
import React, { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
export default function UserAccount() {
let navigate = useNavigate();
useEffect(() => {
let authToken = sessionStorage.getItem('access')
// if user is not authed, redirect user to login page
if (!authToken) {
navigate('/login')
}
}, [])
return (
<div>
Home Page
</div>
)
}
答案使用功能组件和 React 路由器 v6+。如果您提供您使用的 react-router 版本,我可以更新我的答案
您忘记添加检查天气用户是否已授权的条件。为此,您需要检查 UserAccount 页面。我提供了片段。条件应该写在功能组件的 useEffect
里面。 componentDidMount
内基于 class 的组件。可以找到有关身份验证的更多信息
here
除此之外,您还应该在 Login
页面和 Register
页面内添加条件。为了防止用户重新注册和重新登录。
好吧,我可能找到了解决方案。由于我在商店中将空值设置为默认值,因此我更改了我的 PrivateRoute 代码以检查它是否为空,如果是,我们等待渲染或重定向,直到它变为真或假:
import React from 'react'
import {Route, Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
const PrivateRoute = ({component : Component, auth, ...rest}) => (
<Route {...rest} render={props => {
if(auth.isLoading){
return <h2>LOADING ...</h2>
}
else if(auth.isAuthenticated==null){
return <h2>LOADING ...</h2>
}
else if(auth.isAuthenticated==false){
return <h2>Not authenticated ... redirecting here</h2>
}
else{
return <Component {...props}/>
}
}}></Route>
)
const mapStateToProps = state =>({
auth: state.auth,
})
export default connect(mapStateToProps,null)(PrivateRoute);
谁能告诉我这是好主意还是坏主意?