组件在 history.push() 之后没有被渲染

Nee*_*ani 8 browser-history history.js reactjs react-router

单击按钮时,我通过执行更改了 URL history.push()

import createHistory from 'history/createBrowserHistory'  
const history = createHistory()  
.  
. some code  
.  
history.push(`/share/${objectId}`)
Run Code Online (Sandbox Code Playgroud)

并希望该RouteURL 中提到的组件能够呈现,但这并没有发生。但是,刷新该组件时会按预期呈现。但是我不明白为什么它不会在 URL 更改时立即呈现。我试过将组件包装在withRouter.

import React, {Component} from 'react'  
import {BrowserRouter, Router, Route, Switch, withRouter} from 'react-router-dom'  
import createHistory from 'history/createBrowserHistory'  

import Home from './pages/home'  
import ViewFile from './pages/view-file'  

const history = createHistory()

class App extends Component {
    constructor(props) {
      super(props)
    }

      render() {
      return (
          <BrowserRouter>
              <Switch>
                  <Route exact path={'/'} component={Home}/>
                  <Route path={'/share/:id'} component={withRouter(ViewFile)}/>
              </Switch>
          </BrowserRouter>
      )
  }
}

export default App 
Run Code Online (Sandbox Code Playgroud)

以及通过历史Router,我认为与使用BrowserRouter

import React, {Component} from 'react'  
import {BrowserRouter, Router, Route, Switch, withRouter} from 'react-router-dom'  
import createHistory from 'history/createBrowserHistory'  

import Home from './pages/home'  
import ViewFile from './pages/view-file'  

const history = createHistory()

class App extends Component {
    constructor(props) {
      super(props)
    }

      render() {
      return (
          <Router history={history}>
              <Switch>
                  <Route exact path={'/'} component={Home}/>
                  <Route path={'/share/:id'} component={ViewFile}/>
              </Switch>
          </Router>
      )
  }
}

export default App 
Run Code Online (Sandbox Code Playgroud)

但没有得到任何运气。谁能解释为什么会这样?
PS我在这里浏览了答案但它们没有帮助

Mat*_*tta 12

每次调用createHistory(). 如果您正在使用,react-router-dom您可以简单地使用withRouterHOC 将history对象通过prop. 然后您将使用history.push('/'),或者如果它在 a 中class componentthis.props.history.push('/')等等。

工作示例https : //codesandbox.io/s/p694ln9j0

路线history在 内定义routes

import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import ScrollIntoView from "../components/ScrollIntoView";

const history = createBrowserHistory();

export default () => (
  <Router history={history}>
    <div>
      <ScrollIntoView>
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
        <Header />
      </ScrollIntoView>
    </div>
  </Router>
);
Run Code Online (Sandbox Code Playgroud)

components/Header.js(我们想要访问history,但是,有时我们必须使用,withRouter因为像Header这样的组件并不驻留在<Route "/example" component={Header}/>HOC 中,所以它不知道我们的路由)

import React from "react";
import { withRouter } from "react-router-dom";

const Header = ({ history }) => (
  <header>
    <nav style={{ textAlign: "center" }}>
      <ul style={{ listStyleType: "none" }}>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/")}>Home</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/about")}>About</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/contact")}>Contact</button>
        </li>
      </ul>
    </nav>
  </header>
);

export default withRouter(Header);
Run Code Online (Sandbox Code Playgroud)

components/Home.js(类似的组件Home知道路由并且history已经通过<Route path="/" component={Home} />HOC传入了对象,所以withRouter不是必需的)

import React from "react";

const Home = ({ history }) => (
  <div className="container">
    <button
      className="uk-button uk-button-danger"
      onClick={() => history.push("/notfound")}
    >
      Not Found
    </button>
    <p>
      ...
    </p>
  </div>
);

export default Home;
Run Code Online (Sandbox Code Playgroud)

与上面相同的概念,但是,如果您不想使用withRouter,那么您可以简单地创建一个history实例,该实例将在需要它的组件之间共享。您将使用importhistory实例并使用等进行导航history.push('/');

工作示例https : //codesandbox.io/s/5ymj657k1k

历史history在自己的文件中定义)

import { createBrowserHistory } from "history";

const history = createBrowserHistory();

export default history;
Run Code Online (Sandbox Code Playgroud)

路线(导入historyroutes

import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import ScrollIntoView from "../components/ScrollIntoView";
import history from "../history";

export default () => (
  <Router history={history}>
    <div>
      <ScrollIntoView>
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
        <Header />
      </ScrollIntoView>
    </div>
  </Router>
);
Run Code Online (Sandbox Code Playgroud)

components/Header.js(导入historyHeader

import React from "react";
import history from "../history";

const Header = () => (
  <header>
    <nav style={{ textAlign: "center" }}>
      <ul style={{ listStyleType: "none" }}>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/")}>Home</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/about")}>About</button>
        </li>
        <li style={{ display: "inline", marginRight: 20 }}>
          <button onClick={() => history.push("/contact")}>Contact</button>
        </li>
      </ul>
    </nav>
  </header>
);

export default Header;
Run Code Online (Sandbox Code Playgroud)

components/Home.js(仍然知道路由并且history对象已经通过<Route path="/" component={Home} />HOC传入,因此history不需要导入,但是如果您愿意,您仍然可以导入它——只是不要historyHome's 中解构函数参数)

import React from "react";

const Home = ({ history }) => (
  <div className="container">
    <button
      className="uk-button uk-button-danger"
      onClick={() => history.push("/notfound")}
    >
      Not Found
    </button>
    <p>
      ...
    </p>
  </div>
);

export default Home;
Run Code Online (Sandbox Code Playgroud)

但你可能会想,那BrowserRouter呢?嗯,BrowserRouter有它自己的内部history对象。我们可以再次使用withRouter访问其history. 在这种情况下,我们甚至根本不需要createHistory()

工作示例https : //codesandbox.io/s/ko8pkzvx0o

路线

import React from "react";
import { BrowserRouter, Route, Switch } from "react-router-dom";
import Header from "../components/Header";
import Home from "../components/Home";
import About from "../components/About";
import Contact from "../components/Contact";
import Notfound from "../components/Notfound";
import ScrollIntoView from "../components/ScrollIntoView";

export default () => (
  <BrowserRouter>
    <div>
      <ScrollIntoView>
        <Header />
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
          <Route component={Notfound} />
        </Switch>
        <Header />
      </ScrollIntoView>
    </div>
  </BrowserRouter>
);
Run Code Online (Sandbox Code Playgroud)


A H*_*A H 10

这可能会帮助某人。确保history软件包版本与react-router-dom.

这种组合并没有为我工作:

历史:5.0.0使用 react-router-dom:5.2.0

这个组合做到了

历史:4.10.1使用 react-router-dom5.2.0


小智 8

使用import { Router }代替import { BrowserRouter as Router }. 因为 BrowserRouter 忽略了 history 道具。