反应,管理不同的路由器历史
React, manage different router history
我的网站上有一个 BrowserRouter 服务于 /、/login 和 /logout。
登录后,您访问的应用程序在每个页面上都具有相同的导航栏和包含 data/functionalities 的动态内容。
这个模板组件 "Main" 有一个 HashRouter 来为应用程序的不同页面提供服务。
我在我的导航栏中添加了一个搜索表单 "CMNav" 但当用户验证该表单时,我无法使用历史记录进行重定向。
CMNav 通过 withRouter 访问 BrowserRouter 的历史记录,但看不到 HashRouter 的历史记录,因为他是在同一级别定义的。
因此,当我键入搜索并按回车键时,我的 URL 更改为 /search 但未完成对搜索组件的重定向(因为我正在使用错误的历史对象)。
关于如何解决这个问题的任何帮助?
我的切入点是index.js。
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Redirect, Route, Switch } from "react-router-dom";
import Main from "./Main";
import Login from "./auth/login";
const Router = require("react-router");
const auth = require("./auth/auth");
ReactDOM.render(
<div>
<BrowserRouter history={Router.browserHistory}>
<Switch>
<Route
path="/login"
render={() => (auth.loggedIn() ? <Redirect to="/" /> : <Login />)}
/>
<Route
path="/logout"
render={() => {
auth.logout();
return <Redirect to="/login" />;
}}
/>
<Route
path="/"
render={() => (auth.loggedIn() ? <Main /> : <Redirect to="/login" />)}
/>
</Switch>
</BrowserRouter>
</div>,
document.getElementById("root")
);
当用户登录后,他会被重定向到“/”并调用 "Main" 组件。
Main.jsx
import React, { Component } from "react";
import { HashRouter, Route } from "react-router-dom";
import Home from "./pages/Home";
import Search from "./pages/Search";
import CMNav from "./components/cm-nav";
class Main extends Component {
constructor(props) {
super(props);
this.state = {};
this.componentDidMount = this.componentDidMount.bind(this);
}
componentDidMount() {
// Do things
}
render() {
return (
<div>
<div className="container-fluid">
<CMNav />
<HashRouter>
<div>
<Route exact path="/" component={Home} />
<Route path="/search" component={Search} />
</div>
</HashRouter>
</div>
</div>
);
}
}
export default Main;
cm-nav.jsx
import React, { Component } from "react";
import { withRouter } from 'react-router-dom';
import { MenuItem, Nav, Navbar, NavDropdown, NavItem } from "react-bootstrap";
import TextInput from "./text-input";
class CMNav extends Component {
constructor(props) {
super(props);
this.navSearchCallback = this.navSearchCallback.bind(this);
}
navSearchCallback(searchedText) {
// Meant to be a prop
this.props.history.push({
pathname: "/#/search",
state: { searchedText: searchedText }
});
}
render() {
return (
<Navbar collapseOnSelect fluid>
<Navbar.Header>
<Navbar.Brand>
<a href="#">
<img
className={"img-thumbnail img_logo_small"}
src={"images/logo.png"}
data-holder-rendered="true"
/>
</a>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav>
<NavItem eventKey={1} href="#search"> Recherche </NavItem>
</Nav>
<Nav pullRight>
<NavItem eventKey={1}> <TextInput callback={(param) => {this.navSearchCallback(param)}}/> </NavItem>
</Nav>
</Navbar.Collapse>
</Navbar>
);
}
}
export default withRouter(CMNav);
我建议执行以下操作:
- 确保您的依赖项是最新的,特别是 react 和 react-router-dom
- 如果您使用的是最新版本的 react-router-dom,则无需导入或使用 react-router 包。您应该使用
导入路由器组件
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
- 阅读文档,react-router-dom 包已经存在了一段时间,并且有很好的文档记录,并且在生产中经过了实战测试。下面的link有一个很好的介绍例子:https://reacttraining.com/react-router/web/example/basic。您还应该阅读 withRouter 和 history 部分。
- 您可以删除以下组件属性,至少对于最新版本的 react-router-dom,它是多余的:
<BrowserRouter **history={Router.browserHistory}**>
没关系,答案就像将 CMNav 放入 HashRouter 中一样简单....
<HashRouter>
<div>
<CMNav />
<Route exact path="/" component={Home} />
<Route path="/search" component={Search} />
</div>
</HashRouter>
我的网站上有一个 BrowserRouter 服务于 /、/login 和 /logout。 登录后,您访问的应用程序在每个页面上都具有相同的导航栏和包含 data/functionalities 的动态内容。 这个模板组件 "Main" 有一个 HashRouter 来为应用程序的不同页面提供服务。
我在我的导航栏中添加了一个搜索表单 "CMNav" 但当用户验证该表单时,我无法使用历史记录进行重定向。
CMNav 通过 withRouter 访问 BrowserRouter 的历史记录,但看不到 HashRouter 的历史记录,因为他是在同一级别定义的。
因此,当我键入搜索并按回车键时,我的 URL 更改为 /search 但未完成对搜索组件的重定向(因为我正在使用错误的历史对象)。
关于如何解决这个问题的任何帮助?
我的切入点是index.js。
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Redirect, Route, Switch } from "react-router-dom";
import Main from "./Main";
import Login from "./auth/login";
const Router = require("react-router");
const auth = require("./auth/auth");
ReactDOM.render(
<div>
<BrowserRouter history={Router.browserHistory}>
<Switch>
<Route
path="/login"
render={() => (auth.loggedIn() ? <Redirect to="/" /> : <Login />)}
/>
<Route
path="/logout"
render={() => {
auth.logout();
return <Redirect to="/login" />;
}}
/>
<Route
path="/"
render={() => (auth.loggedIn() ? <Main /> : <Redirect to="/login" />)}
/>
</Switch>
</BrowserRouter>
</div>,
document.getElementById("root")
);
当用户登录后,他会被重定向到“/”并调用 "Main" 组件。
Main.jsx
import React, { Component } from "react";
import { HashRouter, Route } from "react-router-dom";
import Home from "./pages/Home";
import Search from "./pages/Search";
import CMNav from "./components/cm-nav";
class Main extends Component {
constructor(props) {
super(props);
this.state = {};
this.componentDidMount = this.componentDidMount.bind(this);
}
componentDidMount() {
// Do things
}
render() {
return (
<div>
<div className="container-fluid">
<CMNav />
<HashRouter>
<div>
<Route exact path="/" component={Home} />
<Route path="/search" component={Search} />
</div>
</HashRouter>
</div>
</div>
);
}
}
export default Main;
cm-nav.jsx
import React, { Component } from "react";
import { withRouter } from 'react-router-dom';
import { MenuItem, Nav, Navbar, NavDropdown, NavItem } from "react-bootstrap";
import TextInput from "./text-input";
class CMNav extends Component {
constructor(props) {
super(props);
this.navSearchCallback = this.navSearchCallback.bind(this);
}
navSearchCallback(searchedText) {
// Meant to be a prop
this.props.history.push({
pathname: "/#/search",
state: { searchedText: searchedText }
});
}
render() {
return (
<Navbar collapseOnSelect fluid>
<Navbar.Header>
<Navbar.Brand>
<a href="#">
<img
className={"img-thumbnail img_logo_small"}
src={"images/logo.png"}
data-holder-rendered="true"
/>
</a>
</Navbar.Brand>
<Navbar.Toggle />
</Navbar.Header>
<Navbar.Collapse>
<Nav>
<NavItem eventKey={1} href="#search"> Recherche </NavItem>
</Nav>
<Nav pullRight>
<NavItem eventKey={1}> <TextInput callback={(param) => {this.navSearchCallback(param)}}/> </NavItem>
</Nav>
</Navbar.Collapse>
</Navbar>
);
}
}
export default withRouter(CMNav);
我建议执行以下操作:
- 确保您的依赖项是最新的,特别是 react 和 react-router-dom
- 如果您使用的是最新版本的 react-router-dom,则无需导入或使用 react-router 包。您应该使用 导入路由器组件
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
- 阅读文档,react-router-dom 包已经存在了一段时间,并且有很好的文档记录,并且在生产中经过了实战测试。下面的link有一个很好的介绍例子:https://reacttraining.com/react-router/web/example/basic。您还应该阅读 withRouter 和 history 部分。
- 您可以删除以下组件属性,至少对于最新版本的 react-router-dom,它是多余的:
<BrowserRouter **history={Router.browserHistory}**>
没关系,答案就像将 CMNav 放入 HashRouter 中一样简单....
<HashRouter>
<div>
<CMNav />
<Route exact path="/" component={Home} />
<Route path="/search" component={Search} />
</div>
</HashRouter>