每次调用createHistory() 时都会创建新的历史记录。如果您使用react-router-dom,您可以简单地使用withRouter HOC,它将通过prop 将history 对象提供给组件。然后您将使用history.push('/'),或者如果它位于class component、this.props.history.push('/') 等中。
工作示例:https://codesandbox.io/s/p694ln9j0
路由(在routes 中定义history)
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>
);
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);
components/Home.js(像Home 这样的组件知道路由并且已经通过<Route path="/" component={Home} /> HOC 传入了history 对象,所以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;
但是,如果您不想使用withRouter,则与上面的概念相同,那么您可以简单地创建一个history 实例,该实例将在需要它的组件之间共享。您将import 这个history 实例并使用history.push('/'); 导航等等。
工作示例:https://codesandbox.io/s/5ymj657k1k
历史(在自己的文件中定义history)
import { createBrowserHistory } from "history";
const history = createBrowserHistory();
export default history;
路由(将history 导入routes)
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>
);
components/Header.js(将history 导入Header)
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;
components/Home.js(仍然知道路由并且已经通过 <Route path="/" component={Home} /> HOC 传入了 history 对象,因此不需要导入 history,但是您如果你愿意,仍然可以导入它——只是不要在Home的函数参数中解构history)
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;
但你可能会想,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>
);