reactjs - 切换路由时 React 不会重新运行 App() 函数
问题描述
我有一个 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>
</>
);
}
}
/dashboard
如果登录过程成功,我的 Login.js 组件会将用户重定向到路径。问题是它仍然加载说要登录的页面。如果我重新加载页面,它会显示实际的仪表板。
我发生这种情况是因为(我猜)React 只是在路由之间切换,从/login
to /*
( /dashboard
) 但它不会重新运行该App()
函数,因此它无法重做if(resultat!==null)
测试。
我想如果我试图在进入仪表板时强制 React 重新加载页面(我试过这个答案)但它没有用。
有什么办法可以实现我想要做的吗?
提前致谢。
解决方案
感谢@FeedThePiano 的帮助,我能够弄清楚。
问题是,即使我使用状态来存储userInfo
状态,用户登录时也没有更新(因为登录过程发生在<Login/>
组件中)。所以我需要找到一种方法来更新<Login/>
组件的状态。
react-redux
提供了一种方法来做到这一点,这就是我的做法:
-我创建了一个减速器,Reducers\signInReducer.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);
}
}
-我曾经Reducers\index.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
状态会按时更新,并且重定向没有问题。
推荐阅读
- linker - 创建并链接目标代码后,符号表会发生什么变化?
- javascript - 如何通过单击一个来选择两个表格单元格?
- python - 将列表中的可能值添加到 groupby 结果
- apache-kafka - 由于组重新平衡,Spring Cloud Stream Kafka 提交失败
- azure-functions - 如何在 Azure 函数中使用 ArangoJS
- swift - 如何在 iOS 的 TikTok 上分享视频?
- apache - Magento 2.2.6 + Apache + varnish 4. 似乎 url 重写不起作用
- javascript - 加载静态资源失败
- asynchronous - 带有管道工的异步 API 端点
- c++ - 在多项目 Visual Studio 解决方案中编译不同配置的项目