Вы создаете новую историю каждый раз, когда вызываете createHistory()
. Если вы используете react-router-dom
, вы можете просто использовать withRouter
HOC, который будет поставлять объект history
компоненту через prop
. Затем вы будете использовать history.push('/')
, или если оно в class component
, this.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>
);
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
знает о маршрутизации и уже имеет объект 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;
Та же концепция, что и выше, однако, если вы не хотите использовать 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>
);
компонентов / 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 (все еще знает о маршрутизации и уже имеет объект history
, переданный через <Route path="/" component={Home} />
HOC, поэтому импорт history
не требуется, но вы можете все равно импортируйте его, если хотите - просто не разбирайте history
в параметрах функции Home
)
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>
);