单击按钮后,我通过执行history.push()
import createHistory from 'history/createBrowserHistory'
const history = createHistory()
.
. some code
.
history.push(`/share/${objectId}`)
,并希望该URL的Route
中提到的组件可以呈现,但不会发生。但是,在刷新时,该组件正按预期方式呈现。但是我不明白为什么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
中传递 history ,我认为这与使用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,但他们没有帮助
答案 0 :(得分:5)
使用import { Router }
代替import { BrowserRouter as Router }
。
因为BrowserRouter会忽略历史记录道具。
答案 1 :(得分:2)
检查 react、react-router、react-router-dom 和 history 包版本也无效的版本 – 我的配置 package.json
"history": "^4.10.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-router": "5.1.2",
"react-router-dom": "5.1.2"
检查此链接:- https://stackblitz.com/edit/react-34ohqv?embed=1&file=package.json https://stackblitz.com/edit/react-router-example-mahi-hzitgg?embed=1&file=index.js
答案 2 :(得分:1)
您每次调用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>
);
答案 3 :(得分:1)
将历史包降级为历史:4.10.1 with react-router-dom 5.2.0 对我有用
答案 4 :(得分:0)
几点:
1)使用import { Router} from 'react-router-dom'
而不是import { BrowserRouter as Router} from 'react-router-dom'
2)在另一个文件(可以更改)history
中创建变量../src/services/history.js
,内容应为:
import { createBrowserHistory } from 'history';
const history = createBrowserHistory();
export default history;
您必须通过react-history
安装npm install --save react-history
软件包
3)将历史记录导入主文件,并将其传递到路由器组件内部。
import React from 'react';
import { Router, Route, Switch } from 'react-router-dom'
import history from './services/history'
class App extends React.Component {
render() {
return (
<Router history={history}>
<Switch>
<Route exact path='/' component={MainPage}></Route>
<Route exact path='/vendor' component={VendorPage}></Route>
<Route exact path='/client' component={ClientPage}></Route>
</Switch>
</Router>
);
}
}
export default App;
4)现在,您可以在组件中的任何位置使用history
,
import React from 'react'
import history from '../services/history';
export default class VendorPage extends React.Component {
loginUser = () => {
if (<SOME_CONDITION>)
history.push('/client')
}
render() {
return (
<h1>Welcome to Vendor Page....</h1>
)
}
}
希望对您有帮助。
:)
答案 5 :(得分:0)
这可能会帮助某人。确保history
软件包版本与react-router-dom
兼容。
此组合没有对我有用:
历史记录:5.0.0
,带有react-router-dom:5.2.0
此组合完成:
历史记录:4.10.1
,带有react-router-dom 5.2.0
答案 6 :(得分:0)
对于使用钩子的人,使用 useLocation()
钩子代替 useHistory()
有效。
const { pathname } = useLocation();
每次路径名更改时组件都会重新渲染。
答案 7 :(得分:0)
使用这个:
import { useHistory, useRouteMatch } from 'react-router-dom';
let history = useHistory();
let match = useRouteMatch();