简体   繁体   English

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

[英]React, manage different router history

I have a BrowserRouter serving /, /login, and /logout on my website.我的网站上有一个 BrowserRouter 服务于 /、/login 和 /logout。 When logged in, you access an app with the same navbar on every page and a dynamic content that holds the data/functionalities.登录后,您可以访问每个页面上具有相同导航栏和包含数据/功能的动态内容的应用程序。 This template component, "Main", has a HashRouter to serve the different pages of the application.这个模板组件“Main”有一个 HashRouter 来为应用程序的不同页面提供服务。

I added a search form in my navbar "CMNav" but I'm stuck using history to redirect when the user validates the form.我在导航栏“CMNav”中添加了一个搜索表单,但是当用户验证表单时,我无法使用历史记录进行重定向。

CMNav accesses the history of the BrowserRouter thanks to withRouter but can't see the history of the HashRouter as he was defined at the same level.由于withRouter,CMNav访问了BrowserRouter的历史,但无法看到HashRouter的历史,因为他是在同一级别定义的。

So when I type a search and hit enter key, my URL changes to /search but the redirection to the Search component is not done (as I'm playing with the wrong history object).因此,当我键入搜索并按 Enter 键时,我的 URL 更改为 /search,但未完成重定向到 Search 组件(因为我正在使用错误的历史记录对象)。

Any help on how to solve this issue?有关如何解决此问题的任何帮助?

My entry point is index.js.我的入口点是 index.js。

index.js索引.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")
);

When the user is logged he gets redirect to "/" and the "Main" component is called.当用户登录时,他被重定向到“/”并调用“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 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);

I would suggest doing the following:我建议执行以下操作:

  1. Make sure your dependencies are up to date, specifically react and react-router-dom确保您的依赖项是最新的,特别是 react 和 react-router-dom
  2. If you are using the most recent version of react-router-dom, you don't need to import or use the react-router package.如果您使用的是最新版本的 react-router-dom,则不需要导入或使用 react-router 包。 You should import the router components with the您应该使用以下命令导入路由器组件

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

  1. Read the documentation, the react-router-dom package has been around for a while and is well documented as well as being battle-tested in production.阅读文档,react-router-dom 包已经存在了一段时间,并且有很好的文档记录并且在生产中经过了实战测试。 The following link has a great introduction example: https://reacttraining.com/react-router/web/example/basic .以下链接有一个很好的介绍示例: https : //reacttraining.com/react-router/web/example/basic You should also read the withRouter and history sections.您还应该阅读 withRouter 和历史记录部分。
  2. You can remove the following component prop as, at least with the most recent version of react-router-dom, it is redundant: <BrowserRouter **history={Router.browserHistory}**>您可以删除以下组件道具,至少在最新版本的 react-router-dom 中,它是多余的: <BrowserRouter **history={Router.browserHistory}**>

Nevermind, the answer is as easy as putting CMNav inside HashRouter....没关系,答案就像将 CMNav 放在 HashRouter 中一样简单......

      <HashRouter>
        <div>
          <CMNav />

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM