反应,管理不同的路由器历史

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);

我建议执行以下操作:

  1. 确保您的依赖项是最新的,特别是 react 和 react-router-dom
  2. 如果您使用的是最新版本的 react-router-dom,则无需导入或使用 react-router 包。您应该使用
  3. 导入路由器组件

import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";

  1. 阅读文档,react-router-dom 包已经存在了一段时间,并且有很好的文档记录,并且在生产中经过了实战测试。下面的link有一个很好的介绍例子:https://reacttraining.com/react-router/web/example/basic。您还应该阅读 withRouter 和 history 部分。
  2. 您可以删除以下组件属性,至少对于最新版本的 react-router-dom,它是多余的:<BrowserRouter **history={Router.browserHistory}**>

没关系,答案就像将 CMNav 放入 HashRouter 中一样简单....

      <HashRouter>
        <div>
          <CMNav />

          <Route exact path="/" component={Home} />
          <Route path="/search" component={Search} />
        </div>
      </HashRouter>