我正在尝试更改应用的根目录,以在用户进行身份验证时呈现其他路由器。 (登录后是公共营销网站,然后是SAAS应用)。
我当前的代码:
class MainRouter extends React.Component {
render() {
if(isAuthenticated()) {
return <AppRouter/>
} else {
return <FrontRouter/>
}
}
}
这可行,但是我必须在身份验证或注销后刷新浏览器,否则尝试呈现需要用户的组件时会抛出错误。
已认证:
export const isAuthenticated = () => {
if(typeof window == 'undefined') {
return false
}
if(localStorage.getItem('jwt')) {
return JSON.parse(localStorage.getItem('jwt'))
} else {
return false;
}
};
考虑使用状态(最好是带有钩子,或者如果愿意的话,可以使用Redux)将JWT保留在内存中。这个想法是在登录后立即存储它,并使其可以通过组件(或Redux)状态使用。然后,刷新页面后,状态仍将从localState或cookie中加载。
次要点,LocalStorage可以在不同的浏览器中采取不同的行动,甚至在隐私设置方面也是如此。考虑使用cookie而不是localStorage,因为它的用法更可预测且更一致,并且安全风险或多或少相同。 (下面的代码示例)
第三,我强烈建议从基于类的组件切换到基于函数的组件,以利用React的新Hooks API。这是一种管理状态并节省许多代码的简单方法。
// library imports
import React from 'react';
// component imports
import AppRouter from './AppRouter';
import FrontRouter from './FrontRouter';
// main
export default function MainRouter({isAuthenticated}) {
return isAuthenticated ? <AppRouter/> : <FrontRouter/>
}
如果“ isAuthenticated”是由React的“ useState”函数从父组件创建的布尔变量,则可以将该变量传递给“ MainRouter”组件并有条件地呈现“ AppRouter”或“ FrontRouter”(我使用的是三元运算符“ If / Else”语句以保存行)
在这种情况下,父组件文件将如下所示:
// in ParentComponent.jsx
// library imports
import React, {useState} from 'react';
// component imports
import MainRouter from './MainRouter';
// main component
export default function ParentComponent() {
// set state here
const defaultState = false;
const [isAuthenticated, setIsAuthenticated] =useState(defaultState);
return (
<div className="ParentComponent" >
<MainRouter isAuthenticated={isAuthenticated} />
</div>
)
}
用于从w3schools获取Cookie的辅助功能(https://www.w3schools.com/js/js_cookies.asp)
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}