单击按钮,我通过执行history.push()
来更改URL
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
.
. some code
.
history.push(`/share/${objectId}`)
并希望Route
中提到的该URL的组件将呈现,但这不会发生。但是,在刷新时,该组件将按预期呈现。但我不明白为什么一旦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
以及在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
但是没有运气。谁能解释为什么会这样? P.S我经历了here的答案,但他们没有帮助
每次调用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
HOC传递了<Route path="/" component={Home} />
对象,因此不需要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(仍然知道路由并且已经通过history
HOC传递了<Route path="/" component={Home} />
对象,因此不需要导入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>
);