reactjs - 在 React 中重定向到具有不同页面布局的页面
问题描述
成功登录后,我无法重定向到具有不同 CSS 布局的页面。例如,我有一个带有典型导航栏的公司页面,如主页、关于我们、服务和登录。成功登录后,它会重定向到类似 Admin Bootstrap Dashboard 页面。但我不断获得公司页面导航栏,但 url 清楚地显示 localhost:3000/dashboard。我哪里做错了?谢谢,代码如下:
App.js
<Switch>
<Fragment>
<Helmet>
<title>Demo</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<meta content="" name="keywords"/>
<meta content="" name="description"/>
</Helmet>
<Header/>
<Route exact path="/" component={Home}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/services" component={Services}/>
</Fragment>
</Switch>
In the Login.js
render() {
if(this.state.isAuthenticated){
return(<Redirect to={'/Dashboard'}/>)
}
In the Dashboard.js
render() {
return (
<div>
<h1>Hello</h1>
</div>
)
}
}
解决方案
将 isUserAuthenticated 之类的状态变量存储在受保护的 Route 中是一个坏主意,在您的情况下,它就是仪表板。让我解释一下上面的代码是做什么的,它首先呈现仪表板组件,然后在第一次安装仪表板之后,代码决定用户是否经过身份验证并有条件地重定向。还要提到变量 unauthenticated 是组件级别的状态,这意味着其他组件无法知道用户是否经过身份验证。
现在它可能会出错,您可能需要标题组件中用户的身份验证状态,如果用户通过身份验证或登录按钮,您将在其中呈现注销按钮。其他一些组件可能还需要用户的身份验证状态。
因此,最好的方法是使用更好的状态管理,如上下文 API 或 redux,如果您对它感到满意的话。
是否使用 redux 完全是另一回事。所以这里有一个使用上下文 API 来解决问题的简单解决方案。
在 AuthContext.js 中
const AuthContext = React.CreateContext(null)
const AuthContextProvider = (props) => {
const [isAuthenticated, setIsAuthenticated] = useState(false)
const login = () => {
// your authentication logic
setIsAuthenticated(true)
}
const logout = () => {
// your logout logic
setIsAuthenticated(false)
}
return (
<AuthContext.Provider value={{isAuthenticated, login, logout}}>
{props.children}
<AuthContext.Provider>
)
}
export default AuthContextProvider;
在 App.js 中使用 AuthContextProvider 包装您的应用
function App(props) {
return (
<AuthContextProvider>
// all other app logic
// like <Switch>
// <Route exact path="/" component={Home}/>
// <Switch/>
<AuthContextProvider>
)
}
现在要使仪表板路由受到保护,您可以采用这种方法制作一个新的私有路由组件
在 PrivateRoute.js
function PrivateRoute(props) {
// keep in mind path is required as a prop
const { path, children, ...rest } = props;
// using the AuthContext to get the state variable isAuthenticated
const { isAuthenticated } = useContext(AuthContext);
return (
<Route
exact
path={path}
render={({ location }) =>
isAuthenticated ? (
children
) : (
<Redirect to={{ pathname: '/login', state: { from: location } }} />
)
}
/>
);
}
在您的情况下呈现受保护的页面(如仪表板)时,在 Switch 内呈现这样的路由,任何其他私有路由也是如此
<Switch>
// other routes
// for example <Route exact path="/" component={Home}/>
// The Dashboard route
<PrivateRoute path="/dashboard">
<Dashboard/>
<PrivateRoute/>
<Switch/>
请记住,登录和注销功能来自上下文,因此任何使用登录或注销功能的组件也需要使用 AuthContext。如果您的应用程序已经在使用它,或者您对 redux 更满意,您也可以使用 redux 实现相同的逻辑。
这在代码中实现起来要困难得多,所以让我知道您是否可以在您的应用程序中实现它。
如果您需要参考,这里有一些文档链接。
https://reactjs.org/docs/context.html
https://reacttraining.com/react-router/web/example/auth-workflow
推荐阅读
- r - 我无法让 DT 包在 Rshiny 上正常工作
- c++ - C++ 对待实例化的模板类与非模板类型有什么不同吗?
- html - 使用 flexbox/grid 流畅地调整内容大小
- javascript - 如何在 Rails 6 中使用 ES6、commonJS
- sql - 如何使用时间戳列获取过去 X 天的数据?
- reactjs - 为什么 useState 钩子会这样?
- javascript - 在 reactjs 中使用 axios 插入选择的值
- python-3.x - 计算字符串列表的所有元素中特定字符的出现次数
- tensorflow2.0 - 使用 TensorflowLite 进行目标检测 Few-Shot 训练
- python - 列表麻烦中的 Python 列表