React Redux with hooks - 身份验证和受保护的路由

Posted

技术标签:

【中文标题】React Redux with hooks - 身份验证和受保护的路由【英文标题】:React Redux with hooks - authentication and protected routes 【发布时间】:2020-07-01 18:35:51 【问题描述】:

我正在使用带有钩子、react-redux 和 redux-thunk 的 React,但我不确定我是否正确地进行了身份验证。在 Main.js 中,我调用了一个名为 checkIfLoggedIn() 的操作。这是 Main.js 的内容:

class Main extends React.Component 
    constructor(props) 
        super(props);
        this.props.checkIfLoggedIn();

    

    render() 
        return (
            <BrowserRouter>
                <div style=position: 'relative'>
                    <Navbar/>
                    <div className='container-fluid'>
                        <Route exact path='/' component=(Dashboard)/>
                        <Route exact path='/sale' component=(Sale)/>
                        <Route exact path='/settings' component=(Settings)/>
                        <Route exact path='/login' component=(Login)/>
                    </div>
                </div>
            </BrowserRouter>
        )
    


const mapDispatchToProps = 
    checkIfLoggedIn
;

export default connect(null, mapDispatchToProps)(Main);

这是checkIfLoggedIn()的代码

import SET_ADMIN, SET_LOGGED_IN from "./types";
import axios from 'axios';

export const checkIfLoggedIn = () => async dispatch => 
    const adminToken = window.localStorage.getItem('admin_token');
    if (adminToken === null)
        dispatch(
            type: SET_LOGGED_IN,
            payload: false
        );
    else 
        try 
            const r = await axios.get('/users/me');
            const data = r.data;
            dispatch(
                type: SET_ADMIN,
                payload: data
            );
            dispatch(
                type: SET_LOGGED_IN,
                payload: true
            );

         catch (e) 
            dispatch(
                type: SET_LOGGED_IN,
                payload: false
            );
        
    
;

还有我的初始状态:

const initialState = 
    isLoggedIn: false,
    currentAdmin: 
    ,
;

现在,我想创建一个 ProtectedRoute,在我未登录时将我重定向到 Login 路由。我想在 Login 组件中做类似的事情,将我重定向到 '/' 路由如果我已登录。

但在这两种情况下,我的 prop isLoggedIn 最初设置为 false,并在几毫秒后更新。这是我的登录组件代码,它没有按预期工作:

const Login = props => 

    const dispatch = useDispatch();
    const [redirect, setRedirect] = useState(false);

    dispatch(checkIfLoggedIn());

    useEffect(() => 
            setRedirect(props.isLoggedIn);

    , [props.isLoggedIn]);

    return redirect ? <Redirect to='/' /> : (
    /* the login form code */
    )


表单显示片刻,然后我被重定向到主路由。如何防止显示表单?以及如何让 PrivateRoute 等待片刻以接收所有道具并获得初始 isLoggedIn 状态?

【问题讨论】:

那么你是否只想在用户未登录的情况下进行重定向? 如果登录用户(手动)进入 /login 路由,我想将他重定向到主路由。如果已注销的用户输入任何路线,我想将他重定向到 /login 路线。 【参考方案1】:

不确定我是否完全理解您正在做的事情的背景,但这是我的想法。在您的 useEffect 中,isLoggedIn 布尔值似乎正在控制重定向布尔值,这可能会导致不必要的副作用。

试试这个

const Login = props => 

    const dispatch = useDispatch();
    const [redirect, setRedirect] = useState(false);

    dispatch(checkIfLoggedIn());

    useEffect(() => 
            // If user is not logged in, redirect them
            if (!props.isLoggedIn) 
            setRedirect(true)
     

    , [props.isLoggedIn]);

    return redirect ? <Redirect to='/' /> : (
    /* the login form code */
    )

如果您使用的是 react-router,并且您使用 withRouter 高阶组件导出此组件,则最好使用 history.push 来完成您要完成的任务

const Login = props => 

    const dispatch = useDispatch();
    const [redirect, setRedirect] = useState(false);

    dispatch(checkIfLoggedIn());

    useEffect(() => 
            // If user is not logged in, redirect them
            if (!props.isLoggedIn) 
            props.history.push('/redirectRoute')
     

    , [props.isLoggedIn]);

    return redirect ? <Redirect to='/' /> : (
    /* the login form code */
    )

【讨论】:

好吧,谢谢,但这不起作用。添加if (!props.isLoggedIn)setRedirect(true) 后,我总是被重定向,即使我没有登录。props.isLoggedIn 是假的,然后,几毫秒后它又是真的。但是使用你的代码我会立即被重定向。 哦,我一定是误会了,我以为如果你没有登录,你总是想被重定向

以上是关于React Redux with hooks - 身份验证和受保护的路由的主要内容,如果未能解决你的问题,请参考以下文章

React - Redux Hooks的使用细节详解

React Hooks 与 React-redux

使用 React-Redux Hooks 和 React-Redux Connect() 的主要区别是啥?

react+redux+hooks

使用react-router+hooks搭建基础框架

将 React Hook 和 redux 一起用于 React 功能组件是不是不好?