我有一个React/Node应用程序,它允许用户登录并重定向到他的仪表板。我想要实现的是防止用户去其他页面,如果他没有登录。我的App.js看起来像这样:
function App() {
const userInfo = localStorage.getItem("userInfo");
let resultat = JSON.parse(userInfo);
if(resultat!==null){
if(resultat.status==="ok"){
return (
<>
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route path='/' exact component={ Dashboard }>
</Route>
<Route path='/login' exact component={ Login }>
</Route>
<Route path='/dashboard' exact component={ Dashboard }>
</Route>
<Route path='/other_route' exact component={ OtherComponent }>
</Route>
</Switch>
</Router>
</>
);
} else {
return(
<>
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route path='/' exact component={ Login }>
</Route>
<Route path='/login' exact component={ Login }>
</Route>
<Route path='/*' exact>
<>
You are not logged in. To see this page please, log in.
</>
</Route>
</Switch>
</Router>
</>
);
}
} else {
return(
<>
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route path='/' exact component={ Login }>
</Route>
<Route path='/login' exact component={ Login }>
</Route>
<Route path='/*' exact>
<>
You are not logged in. To see this page please, log in.
</>
</Route>
</Switch>
</Router>
</>
);
}
}
如果登录进程成功,我的login .js组件会将用户重定向到路径/dashboard
。问题是,它仍然会加载说要进入登录的页面。如果我重新加载页面,它会显示实际的仪表板。
我发生是因为(我猜)React只是在路由之间切换,从/login
到/*
(/dashboard
),但它没有重新运行App()
功能,所以它不能重做if(resultat!==null)
测试。
我想,如果我试图强迫React在进入仪表板时重新加载页面(我尝试了这个答案),但它不起作用。
有什么方法可以达到我想要做的吗?
提前感谢。
多亏了@FeedThePiano的帮助,我才弄明白了。
问题是,即使我使用状态来存储userInfo
,当用户登录时状态也不会更新(因为登录过程发生在<Login/>
组件中)。所以我需要找到一种方法来从<Login/>
组件更新状态。
react-redux
提供了一种方法,我是这样做的:
-I创建了一个reducer,ReducerssignInReducer.js
:
const initialState= {
isSignedIn: false
}
export default function signInReducer(state= initialState, action){
switch(action.type){
case "LOGIN":
return{
...state,
isSignedIn: true
}
case "LOGOUT":
return{
...state,
isSignedIn: false
}
default:
return(state);
}
}
-我使用Reducersindex.js
将它与我的其他还原器组合:
import { combineReducers } from "redux";
import otherReducer from "./path/to/other/reducer";
import signInReducer from "./signInReducer";
const allReducers = combineReducers({otherReducer, signInReducer});
export default allReducers;
-然后在我的Login.js
中我添加了:
import React, {useRef, useState} from 'react';
import { useDispatch } from 'react-redux';
export default function login(){
const dispatch= useDispatch();
//Code for the login process
//Login is done..
dispatch({
type: "LOGIN"
});
//We can now redirect (safely)
//Code for redirection
}
-然后我只需要更新我的状态在App.js
:
import {useState, useEffect} from 'react';
import { useSelector, useDispatch } from 'react-redux';
//import the components..
function App() {
const [isUserLoggedIn, setUserLoggedIn]= useState(false);
const [userInfo, setUserInfo]= useState(null);
const isLogged= useSelector(state => state.signInReducer);
useEffect(()=> {
let info= localStorage.getItem("userInfo");
let parsedInfo= JSON.parse(info);
if(parsedInfo!== null){
setUserInfo(parsedInfo.data);
}
},[]);
useEffect(()=> {
if(isLogged.isSignedIn){
setUserLoggedIn(true);
} else {
setUserLoggedIn(false);
}
},[isLogged]);
useEffect(()=> {
if(userInfo!== null){
setUserLoggedIn(true);
} else {
setUserLoggedIn(false);
}
}, [userInfo]);
if(isUserLoggedIn){
return (
<>
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route path='/' exact component={ Dashboard }>
</Route>
<Route path='/login' exact component={ Login }>
</Route>
<Route path='/dashboard' exact component={ Dashboard }>
</Route>
<Route path='/other_route' exact component={ OtherComponent }>
</Route>
</Switch>
</Router>
</>
);
} else {
return(
<>
<Router basename={process.env.PUBLIC_URL}>
<Switch>
<Route path='/' exact component={ Login }>
</Route>
<Route path='/login' exact component={ Login }>
</Route>
<Route path='/*' exact>
<>
You are not logged in. To see this page please, log in.
</>
</Route>
</Switch>
</Router>
</>
);
}
}
这样,userInfo
状态及时更新,重定向工作没有问题。