繁体   English   中英

刷新后反应 Redux 和 state

[英]React Redux and state after refresh

我无法理解为什么我的应用程序工作起来有点奇怪。 当我尝试通过单击导航栏中的链接按钮访问页面上的任何站点时,它会将我导航到那里而没有任何问题,例如当我单击“我的帐户”时,URL 更改为“http://localhost:3000/my_account”一切正常。 在这个地方我不得不提到“/my_account”是一条受保护的路线 - 用户必须登录才能到达它,当他没有登录时 - 他会被发送到主页。 所以现在的问题是,当用户登录并尝试通过输入此 URL 并加载页面来访问“http://localhost:3000/my_account”之类的受保护路由时 - 他被视为未登录用户并被重定向到主页。 在他被重定向到那里并尝试通过单击导航栏链接访问该站点后,他可以进入此页面 - 他已登录。我的预期结果是用户可以在该站点上输入任何 URL 并做出反应,如果他是,则应正确检查在两种情况下都登录 - 单击站点上的链接或提供 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(减速器)中的 state:

const initialState = {
    access: localStorage.getItem('access'),
    refresh: localStorage.getItem('refresh'),
    isAuthenticated: null,
    isLoading : false,
    user: null,
    requestSent: false,
    payload: null,
    message: null
}

并且登录成功后state变化如下:

    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 操作登录 function:

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>
    )
}

Answer 使用功能组件和反应路由器 v6+。 如果您提供您正在使用的 react-router 版本,我可以更新我的答案

您忘记添加检查天气用户是否已通过身份验证的条件。 为此,您需要检查 UserAccount Page 内部。 我提供了片段。 条件应该写在功能组件的useEffect中。 在 componentDidMount 内部基于 class 的componentDidMount内部。 可以在此处找到有关身份验证的更多信息

除此之外,您还应该在Login页面和Register页面中添加条件。 保护用户免于重新注册和重新登录。

好吧,我可能找到了解决方案。 由于我在商店中默认设置了 null 值,因此我更改了 PrivateRoute 代码以检查它是否为 null,如果是,我们等待渲染或重定向,直到它变为 true 或 false:

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);

谁能告诉我这是个好主意还是坏主意?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM