Geo*_*uer 1251 reactjs react-router
随着react-router
我可以使用Link
元素创建的原生处理反应路由器链接.
我看到内部调用this.context.transitionTo(...)
.
我想进行导航,但不是从链接,例如下拉选择.我怎么能在代码中这样做?什么是this.context
?
我看到了Navigation
mixin,但是我可以不用mixin吗?
Pau*_*l S 1161
反应路由器v4
使用React Router的v4,您可以采用三种方法在组件内进行编程路由.
useHistory
高阶组件.withRouter
<Route>
.React Router主要是context
库的包装器.history
通过浏览history
器和哈希历史记录处理与浏览器的交互.它还提供了一个内存历史记录,对于没有全局历史记录的环境非常有用.这在window.history
使用Node的移动应用程序开发()和单元测试中特别有用.
一个react-native
实例有两种导航方法:history
和push
.如果您将其replace
视为已访问位置history
的数组,push
则会向阵列添加新位置,并使用新位置替换阵列中的当前位置.通常,您需要replace
在导航时使用该方法.
在早期版本的阵营路由器,你必须创建自己的push
实例,但在第4版的history
,<BrowserRouter>
和<HashRouter>
组件将创建一个浏览器,哈希和内存的实例为您服务.React Router <MemoryRouter>
通过上下文在history
对象下提供与路由器关联的实例的属性和方法.
router
高阶组件的withRouter
高次成分将注入的withRouter
对象作为所述部件的支柱.这使您可以访问history
和push
方法而无需处理replace
.
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
function handleClick() {
history.push("/home");
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
Run Code Online (Sandbox Code Playgroud)
context
该<Route>
组件不仅适用于匹配位置.您可以渲染无路径路径,它始终与当前位置匹配.该<Route>
元件通过同样的道具的<Route>
,所以您将能够访问withRouter
通过方法history
的道具.
import { withRouter } from 'react-router-dom'
// this also works with react-router-native
const Button = withRouter(({ history }) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
))
Run Code Online (Sandbox Code Playgroud)
但你可能不应该这样做
最后一个选项是您只有在使用React的上下文模型时才能使用的选项.虽然上下文是一个选项,但应该强调上下文是一个不稳定的API,React 在其文档中有一节"不使用上下文".所以使用风险自负!
import { Route } from 'react-router-dom'
const Button = () => (
<Route render={({ history}) => (
<button
type='button'
onClick={() => { history.push('/new-location') }}
>
Click Me!
</button>
)} />
)
Run Code Online (Sandbox Code Playgroud)
1和2是最简单的选择,因此对于大多数用例来说,它们是您最好的选择.
Fel*_*ner 866
React-Router 4.0.0+答案
在4.0及更高版本中,使用历史记录作为组件的支柱.
import { useHistory } from "react-router-dom";
function HomeButton() {
let history = useHistory();
// use history.push('/some/path') here
};
Run Code Online (Sandbox Code Playgroud)
React-Router 3.0.0+答案
在3.0及以上版本中,使用路由器作为组件的支柱.
class Example extends React.Component {
// use `this.props.history.push('/some/path')` here
};
Run Code Online (Sandbox Code Playgroud)
React-Router 2.4.0+答案
在2.4及更高版本中,使用更高阶的组件将路由器作为组件的支柱.
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
Run Code Online (Sandbox Code Playgroud)
React-Router 2.0.0+答案
此版本向后兼容1.x,因此无需升级指南.只是通过这些例子应该足够好了.
也就是说,如果你想切换到新的模式,路由器内部就有一个browserHistory模块可以访问
useHistory
现在您可以访问浏览器历史记录,因此您可以执行推送,替换等操作...
<Route>
React-Router 1.xx答案
我不打算升级细节.您可以在" 升级指南"中阅读相关内容
这里问题的主要变化是从导航mixin到History的变化.现在它正在使用浏览器historyAPI来改变路线,所以我们<Route path="..." component={YourComponent}/>
将从现在开始使用.
这是使用Mixin的例子:
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
var DecoratedExample = withRouter(Example);
// PropTypes
Example.propTypes = {
router: React.PropTypes.shape({
push: React.PropTypes.func.isRequired
}).isRequired
};
Run Code Online (Sandbox Code Playgroud)
请注意,这import { browserHistory } from 'react-router'
来自rackt/history项目.不是来自React-Router本身.
如果您由于某种原因不想使用Mixin(可能是因为ES6类),那么您可以访问从路由器获得的历史记录browserHistory.push('/some/path')
.它只能由路由器呈现的组件访问.因此,如果要在任何子组件中使用它,则需要将其作为属性传递下去pushState()
.
您可以在1.0.x文档中阅读有关新版本的更多信息
它建议抓住一个引用History
并调用this.props.history
它.
React-Router 0.13.x答案
我遇到了同样的问题,只能通过react-router附带的Navigation mixin找到解决方案.
这就是我做到的
var Example = React.createClass({
mixins: [ History ],
navigateToHelpPage () {
this.history.pushState(null, `/help`);
}
})
Run Code Online (Sandbox Code Playgroud)
我props
无需访问就可以打电话history = createHistory()
或者你可以尝试花哨的ES6 replaceState
import React from 'react';
import {Navigation} from 'react-router';
let Authentication = React.createClass({
mixins: [Navigation],
handleClick(e) {
e.preventDefault();
this.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
Run Code Online (Sandbox Code Playgroud)
反应 - 路由器 - 终极版
注:如果您使用的终极版,有一个名为另一个项目 ReactRouter,终极版,为您提供终极版绑定ReactRouter,有些使用了同样的方法 做出反应,终极版呢
React-Router-Redux有一些可用的方法,允许从内部动作创建者进行简单的导航.这些对于在React Native中具有现有体系结构的人来说特别有用,并且他们希望在React Web中使用相同的模式,并且具有最小的样板开销.
探索以下方法:
transitionTo()
.context
class
push(location)
replace(location)
以下是使用Redux-Thunk的示例用法:
./actioncreators.js
import React from 'react';
export default class Authentication extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
}
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
}
Authentication.contextTypes = {
router: React.PropTypes.func.isRequired
};
Run Code Online (Sandbox Code Playgroud)
./viewcomponent.js
import { goBack } from 'react-router-redux'
export const onBackPress = () => (dispatch) => dispatch(goBack())
Run Code Online (Sandbox Code Playgroud)
Bob*_*bby 496
React-Router v2
对于最新版本(v2.0.0-rc5
),推荐的导航方法是直接推送历史单例.您可以在" 组件外部导航"文档中看到该操作.
相关摘录:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
Run Code Online (Sandbox Code Playgroud)
如果使用较新的react-router API,则需要在组件内部使用history
from this.props
,这样:
this.props.history.push('/some/path');
Run Code Online (Sandbox Code Playgroud)
它还提供pushState
但每个已记录的警告已弃用.
如果使用react-router-redux
,它提供了一个push
你可以调度的功能:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
Run Code Online (Sandbox Code Playgroud)
但是,这可能仅用于更改URL,而不是实际导航到页面.
Ale*_*ler 51
以下是react-router v2.0.0
使用ES6执行此操作的方法.react-router
已经离开了mixins.
import React from 'react';
export default class MyComponent extends React.Component {
navigateToPage = () => {
this.context.router.push('/my-route')
};
render() {
return (
<button onClick={this.navigateToPage}>Go!</button>
);
}
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*tin 42
React-Router 4.x答案:
在我的结尾,我喜欢有一个历史对象,我甚至可以携带外部组件.我喜欢做的是拥有一个我按需导入的单个history.js文件,并且只是操作它.
您只需要更改BrowserRouter
为路由器,并指定历史记录道具.这不会改变任何事情,除非你有自己的历史对象,你可以根据需要进行操作.
您需要安装历史记录,使用的库react-router
.
示例用法,ES6表示法:
history.js
import createBrowserHistory from 'history/createBrowserHistory'
export default createBrowserHistory()
Run Code Online (Sandbox Code Playgroud)
BasicComponent.js
import React, { Component } from 'react';
import history from './history';
class BasicComponent extends Component {
goToIndex(e){
e.preventDefault();
history.push('/');
}
render(){
return <a href="#" onClick={this.goToIndex}>Previous</a>;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑2018年4月16日:
如果必须从实际从Route
组件呈现的组件导航,您还可以从props访问历史记录,如下所示:
BasicComponent.js
import React, { Component } from 'react';
class BasicComponent extends Component {
navigate(e){
e.preventDefault();
this.props.history.push('/url');
}
render(){
return <a href="#" onClick={this.navigate}>Previous</a>;
}
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*dko 37
对于这个,谁不控制服务器端,因此使用哈希路由器v2:
将历史记录放入单独的文件中(例如app_history.js ES6):
import { useRouterHistory } from 'react-router'
import { createHashHistory } from 'history'
const appHistory = useRouterHistory(createHashHistory)({ queryKey: false });
export default appHistory;
Run Code Online (Sandbox Code Playgroud)
到处使用它!
您对react-router(app.js ES6)的入口点:
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Redirect } from 'react-router'
import appHistory from './app_history'
...
const render((
<Router history={appHistory}>
...
</Router>
), document.querySelector('[data-role="app"]'));
Run Code Online (Sandbox Code Playgroud)
您在任何组件内导航(ES6):
import appHistory from '../app_history'
...
ajaxLogin('/login', (err, data) => {
if (err) {
console.error(err); // login failed
} else {
// logged in
appHistory.replace('/dashboard'); // or .push() if you don't need .replace()
}
})
Run Code Online (Sandbox Code Playgroud)
Lyu*_*mir 33
反应路由器V4
TL:博士;
if (navigate) {
return <Redirect to="/" push={true} />
}
Run Code Online (Sandbox Code Playgroud)
简单而陈述的答案是你需要<Redirect to={URL} push={boolean} />
结合使用setState()
push:boolean -当为true时,重定向将把新条目推送到历史记录而不是替换当前的条目.
import { Redirect } from 'react-router'
class FooBar extends React.Component {
state = {
navigate: false
}
render() {
const { navigate } = this.state
// here is the important part
if (navigate) {
return <Redirect to="/" push={true} />
}
// ^^^^^^^^^^^^^^^^^^^^^^^
return (
<div>
<button onClick={() => this.setState({ navigate: true })}>
Home
</button>
</div>
)
}
}
Run Code Online (Sandbox Code Playgroud)
PS.该示例使用ES7 +属性初始化程序初始化状态.如果你有兴趣,也可以看看这里.
Qim*_*ing 28
警告:此答案仅涵盖1.0之前的ReactRouter版本
我将用1.0.0-rc1用例更新此答案!
你也可以不用mixin来做到这一点.
let Authentication = React.createClass({
contextTypes: {
router: React.PropTypes.func
},
handleClick(e) {
e.preventDefault();
this.context.router.transitionTo('/');
},
render(){
return (<div onClick={this.handleClick}>Click me!</div>);
}
});
Run Code Online (Sandbox Code Playgroud)
带有上下文的问题是除非你contextTypes
在类上定义它,否则它是不可访问的.
至于什么是上下文,它是一个对象,就像道具一样,从父对象传递到子对象,但它是隐式传递下来的,而不必每次都重新声明道具.请参阅https://www.tildedave.com/2014/11/15/introduction-to-contexts-in-react-js.html
Ben*_*ler 24
在事情正常之前我尝试了至少10种方法!
@Felipe Skinner的withRouter
答案对我来说有点压倒性的,我不确定我是否想制作新的"ExportedWithRouter"类名.
这是最简单,最干净的方法,大约是当前的React-Router 3.0.0和ES6:
带有ES6的React-Router 3.xx:
import { withRouter } from 'react-router';
class Example extends React.Component {
// use `this.props.router.push('/some/path')` here
};
// Export the decorated class
export default withRouter(Example);
Run Code Online (Sandbox Code Playgroud)
或者,如果它不是您的默认类,则导出如下:
withRouter(Example);
export { Example };
Run Code Online (Sandbox Code Playgroud)
请注意,在3.xx中,<Link>
组件本身正在使用router.push
,因此您可以传递任何您传递<Link to=
标签的内容,例如:
this.props.router.push({pathname: '/some/path', query: {key1: 'val1', key2: 'val2'})'
Run Code Online (Sandbox Code Playgroud)
zil*_*nas 23
对于那些已经在使用 React Router v6 的人,可以useNavigate
使用react-router
.
使用这个钩子进行导航非常简单:
import { generatePath, useNavigate } from 'react-router';
navigate(-1); // navigates back
navigate('/my/path'); // navigates to a specific path
navigate(generatePath('my/path/:id', { id: 1 })); // navigates to a dynamic path, generatePath is very useful for url replacements
Run Code Online (Sandbox Code Playgroud)
Has*_*eed 21
对于最新的react-router-dom v6
useHistory()
被替换为useNavigate()
.
您需要使用:
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
navigate('/your-page-link');
Run Code Online (Sandbox Code Playgroud)
Ali*_*eza 20
要以编程方式进行导航,您需要将新历史记录推送到您的props.history中component
,因此这样的事情可以为您完成工作:
//using ES6
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props)
this.handleClick = this.handleClick.bind(this)
}
handleClick(e) {
e.preventDefault()
/* Look at here, you can add it here */
this.props.history.push('/redirected');
}
render() {
return (
<div>
<button onClick={this.handleClick}>
Redirect!!!
</button>
</div>
)
}
}
export default App;
Run Code Online (Sandbox Code Playgroud)
Sof*_*ddy 18
对于ES6 + React组件,以下解决方案适用于我.
我跟着Felippe skinner,但添加了一个端到端的解决方案,以帮助像我这样的初学者.
以下是我使用的版本:
"react-router":"^ 2.7.0"
"反应":"^ 15.3.1"
下面是我的反应组件,我使用react-router进行编程导航:
import React from 'react';
class loginComp extends React.Component {
constructor( context) {
super(context);
this.state = {
uname: '',
pwd: ''
};
}
redirectToMainPage(){
this.context.router.replace('/home');
}
render(){
return <div>
// skipping html code
<button onClick={this.redirectToMainPage.bind(this)}>Redirect</button>
</div>;
}
};
loginComp.contextTypes = {
router: React.PropTypes.object.isRequired
}
module.exports = loginComp;
Run Code Online (Sandbox Code Playgroud)
以下是我的路由器的配置:
import { Router, Route, IndexRedirect, browserHistory } from 'react-router'
render(<Router history={browserHistory}>
<Route path='/' component={ParentComp}>
<IndexRedirect to = "/login"/>
<Route path='/login' component={LoginComp}/>
<Route path='/home' component={HomeComp}/>
<Route path='/repair' component={RepairJobComp} />
<Route path='/service' component={ServiceJobComp} />
</Route>
</Router>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
mck*_*cku 18
可能不是最好的方法但是......使用react-router v4,下面的Typescript可以给出一些想法.
在下面的渲染组件中,例如LoginPage
,router
对象是可访问的,只是调用router.transitionTo('/homepage')
导航.
导航代码取自https://react-router.now.sh/Match.
"react-router": "^4.0.0-2",
"react": "^15.3.1",
import Router from 'react-router/BrowserRouter';
import { History } from 'react-history/BrowserHistory';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
interface MatchWithPropsInterface {
component: typeof React.Component,
router: Router,
history: History,
exactly?: any,
pattern: string
}
class MatchWithProps extends React.Component<MatchWithPropsInterface,any> {
render() {
return(
<Match {...this.props} render={(matchProps) => (
React.createElement(this.props.component, this.props)
)}
/>
)
}
}
ReactDOM.render(
<Router>
{({ router }) => (
<div>
<MatchWithProps exactly pattern="/" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/login" component={LoginPage} router={router} history={history} />
<MatchWithProps pattern="/homepage" component={HomePage} router={router} history={history} />
<Miss component={NotFoundView} />
</div>
)}
</Router>,
document.getElementById('app')
);
Run Code Online (Sandbox Code Playgroud)
Hos*_*ein 16
在React-Router v4和ES6中
你可以使用withRouter
和this.props.history.push
.
import {withRouter} from 'react-router-dom';
class Home extends Component {
componentDidMount() {
this.props.history.push('/redirect-to');
}
}
export default withRouter(Home);
Run Code Online (Sandbox Code Playgroud)
Jan*_*nos 13
要withRouter
与基于类的组件一起使用,请尝试以下方法.不要忘记更改要使用的导出语句withRouter
:
import { withRouter } from 'react-router-dom'
class YourClass extends React.Component {
yourFunction = () => {
doSomeAsyncAction(() =>
this.props.history.push('/other_location')
)
}
render() {
return (
<div>
<Form onSubmit={ this.yourFunction } />
</div>
)
}
}
export default withRouter(YourClass);
Run Code Online (Sandbox Code Playgroud)
pet*_*and 10
随着React-Router v4的出现,现在有了一种新方法.
import { MemoryRouter, BrowserRouter } from 'react-router';
const navigator = global && global.navigator && global.navigator.userAgent;
const hasWindow = typeof window !== 'undefined';
const isBrowser = typeof navigator !== 'undefined' && navigator.indexOf('Node.js') === -1;
const Router = isBrowser ? BrowserRouter : MemoryRouter;
<Router location="/page-to-go-to"/>
Run Code Online (Sandbox Code Playgroud)
react-lego是一个示例应用程序,显示如何使用/更新react-router,它包括导航应用程序的示例功能测试.
Dan*_*Dan 10
根据
JoséAntonioPostigo和Ben Wheeler 之前的回答,
这个新奇事物?是要在Typescript中编写
并使用装饰器
OR 静态属性/字段
import * as React from "react";
import Component = React.Component;
import { withRouter } from "react-router";
export interface INavigatorProps {
router?: ReactRouter.History.History;
}
/**
* Note: goes great with mobx
* @inject("something") @withRouter @observer
*/
@withRouter
export class Navigator extends Component<INavigatorProps, {}>{
navigate: (to: string) => void;
constructor(props: INavigatorProps) {
super(props);
let self = this;
this.navigate = (to) => self.props.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
/**
* Non decorated
*/
export class Navigator2 extends Component<INavigatorProps, {}> {
static contextTypes = {
router: React.PropTypes.object.isRequired,
};
navigate: (to: string) => void;
constructor(props: INavigatorProps, context: any) {
super(props, context);
let s = this;
this.navigate = (to) =>
s.context.router.push(to);
}
render() {
return (
<ul>
<li onClick={() => this.navigate("/home")}>
Home
</li>
<li onClick={() => this.navigate("/about")}>
About
</li>
</ul>
)
}
}
Run Code Online (Sandbox Code Playgroud)
无论今天安装了什么npm."react-router":"^ 3.0.0"和
"@ types/react-router":"^ 2.0.41"
sai*_*945 10
在反应路由器v4中.我按照这两种方式以编程方式进行路由.
1. this.props.history.push("/something/something")
2. this.props.history.replace("/something/something")
Run Code Online (Sandbox Code Playgroud)
第二
替换历史堆栈上的当前条目
要获取道具的历史记录,您可能需要使用包装
withRouter https://reacttraining.com/react-router/core/api/withRouter
Vij*_*122 10
带有钩子的 React Router v6
import {useNavigate} from 'react-router-dom';
let navigate = useNavigate();
navigate('home');
Run Code Online (Sandbox Code Playgroud)
并在浏览器历史记录中移动,
navigate(-1); ---> Go back
navigate(1); ---> Go forward
navigate(-2); ---> Move two steps backward.
Run Code Online (Sandbox Code Playgroud)
如果您使用哈希或浏览器历史记录,那么您可以这样做
hashHistory.push('/login');
browserHistory.push('/login');
Run Code Online (Sandbox Code Playgroud)
您还可以useHistory
在无状态组件中使用钩子。文档中的示例:
import { useHistory } from "react-router"
function HomeButton() {
const history = useHistory()
return (
<button type="button" onClick={() => history.push("/home")}>
Go home
</button>
)
}
Run Code Online (Sandbox Code Playgroud)
注意:添加了钩子
react-router@5.1.0
并且需要react@>=16.8
使用当前的React版本(15.3),this.props.history.push('/location');
对我有用,但它显示以下警告:
browser.js:49警告:[react-router]
props.history
并且context.history
已弃用.请使用context.router
.
我用context.router
这样解决了它:
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.backPressed = this.backPressed.bind(this);
}
backPressed() {
this.context.router.push('/back-location');
}
...
}
MyComponent.contextTypes = {
router: React.PropTypes.object.isRequired
};
export default MyComponent;
Run Code Online (Sandbox Code Playgroud)
这对我有用,不需要特殊导入:
<input
type="button"
name="back"
id="back"
class="btn btn-primary"
value="Back"
onClick={() => { this.props.history.goBack() }}
/>
Run Code Online (Sandbox Code Playgroud)
小智 7
以编程方式在基于类的组件中导航。
import { Redirect } from "react-router-dom";
class MyComponent extends React.Component{
state = {rpath: null}
const goTo = (path) => this.setState({rpath: path});
render(){
if(this.state.rpath){
return <Redirect to={this.state.rpath}/>
}
.....
.....
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
为了简单起见,只需使用useNavigate
最新版本的 React
新文件.js
import { useNavigate } from "react-router-dom";
const Newfile = () => {
const navigate = useNavigate();
....
navigate("yourdesiredlocation");
....
}
export default Newfile;
Run Code Online (Sandbox Code Playgroud)
在您的代码中使用useNavigate
上述功能。
React-Router V4
如果您使用的是版本4,则可以使用我的库(Shameless插件),您可以在其中简单地调度一个动作,并且一切正常!
dispatch(navigateTo("/aboutUs"));
Run Code Online (Sandbox Code Playgroud)
在撰写本文时,正确答案是给我的
this.context.router.history.push('/');
Run Code Online (Sandbox Code Playgroud)
但是您需要将 PropTypes 添加到您的组件中
Header.contextTypes = {
router: PropTypes.object.isRequired
}
export default Header;
Run Code Online (Sandbox Code Playgroud)
不要忘记导入 PropTypes
import PropTypes from 'prop-types';
Run Code Online (Sandbox Code Playgroud)
试试React Hook Router,“react-router 的现代替代品”:
import { useRoutes, usePath, A} from "hookrouter";
Run Code Online (Sandbox Code Playgroud)
要回答 OP 关于通过选择框链接的问题,您可以这样做:
navigate('/about');
Run Code Online (Sandbox Code Playgroud)
我认为 React Hook Router 是一个很好的入门工具包,它帮助我学习了路由,但我已经更新到React Router以了解其历史记录和查询参数处理。
import { useLocation, useHistory } from 'react-router-dom';
const Component = (props) => {
const history = useHistory();
// Programmatically navigate
history.push(newUrlString);
}
Run Code Online (Sandbox Code Playgroud)
您将要导航到的位置推送到 location.history。
也许不是最好的解决方案,但它可以完成工作:
import { Link } from 'react-router-dom';
// Create functional component Post
export default Post = () => (
<div className="component post">
<button className="button delete-post" onClick={() => {
// ... delete post
// then redirect, without page reload, by triggering a hidden Link
document.querySelector('.trigger.go-home').click();
}}>Delete Post</button>
<Link to="/" className="trigger go-home hidden"></Link>
</div>
);
Run Code Online (Sandbox Code Playgroud)
基本上,与一个操作(在本例中为删除后)相关的逻辑最终会调用重定向触发器。这并不理想,因为您将在标记中添加一个DOM节点“触发器”,以便在需要时方便地调用它。此外,您将直接与 DOM 交互,这在 React 组件中可能是不需要的。
不过,这种类型的重定向并不经常需要。因此,组件标记中的一两个额外的、隐藏的链接不会造成太大伤害,尤其是如果您给它们起有意义的名称。
如果您碰巧通过react-router-redux将 RR4 与 redux 配对,react-router-redux
也可以选择使用路由操作创建者。
import { push, replace, ... } from 'react-router-redux'
class WrappedComponent extends React.Component {
handleRedirect(url, replaceState = true) {
replaceState
? this.props.dispatch(replace(url))
: this.props.dispatch(push(url))
}
render() { ... }
}
export default connect(null)(WrappedComponent)
Run Code Online (Sandbox Code Playgroud)
如果您使用 redux thunk/saga 来管理异步流,那么在 redux 动作中导入上述动作创建者并使用 mapDispatchToProps 挂钩到 React 组件可能会更好。
那些在react-router v4上实现此功能时遇到问题的人。
这是一个用于从redux动作浏览react应用程序的可行解决方案。
history.js
import createHistory from 'history/createBrowserHistory'
export default createHistory()
Run Code Online (Sandbox Code Playgroud)
App.js / Route.jsx
import { Router, Route } from 'react-router-dom'
import history from './history'
...
<Router history={history}>
<Route path="/test" component={Test}/>
</Router>
Run Code Online (Sandbox Code Playgroud)
another_file.js或redux文件
import history from './history'
history.push('/test') // this should change the url and re-render Test component
Run Code Online (Sandbox Code Playgroud)
感谢此评论: ReactTraining问题评论
假设您不需要在初始渲染期间进行导航(您可以使用<Redirect>
组件),这就是我们在应用程序中所做的事情。
定义一个返回 null 的空路由。这将允许您访问历史对象。Router
您需要在定义您的顶层执行此操作。
现在你可以做历史上能做的所有事情,比如history.push()
,,,等等history.replace()
!history.go(-1)
import React from 'react';
import { HashRouter, Route } from 'react-router-dom';
let routeHistory = null;
export function navigateTo(path) {
if(routeHistory !== null) {
routeHistory.push(path);
}
}
export default function App(props) {
return (
<HashRouter hashType="noslash">
<Route
render={({ history }) => {
routeHistory = history;
return null;
}}
/>
{/* Rest of the App */}
</HashRouter>
);
}
Run Code Online (Sandbox Code Playgroud)
在我的回答中,可以通过三种不同的方式以编程方式重定向到路由。已经介绍了一些解决方案,但以下解决方案仅针对具有附加演示应用程序的功能组件。
使用以下版本:
反应:16.13.1
反应域:16.13.1
反应路由器:5.2.0
反应路由器-dom:5.2.0
打字稿:3.7.2
配置:
所以首先解决方案是使用HashRouter
,配置如下:
<HashRouter>
// ... buttons for redirect
<Switch>
<Route exact path="/(|home)" children={Home} />
<Route exact path="/usehistory" children={UseHistoryResult} />
<Route exact path="/withrouter" children={WithRouterResult} />
<Route exact path="/redirectpush" children={RedirectPushResult} />
<Route children={Home} />
</Switch>
</HashRouter>
Run Code Online (Sandbox Code Playgroud)
从文档有关<HashRouter>
:
一个
<Router>
使用该URL(即哈希部分window.location.hash
),以确保您的UI同步与URL。
解决方案:
<Redirect>
推送使用useState
:在功能组件(RedirectPushAction
来自我的存储库的组件)中使用我们可以useState
用来处理重定向。棘手的部分是一旦重定向发生,我们需要将redirect
状态设置回false
. 通过延迟使用setTimeOut
,0
我们等待 React 提交Redirect
到 DOM,然后取回按钮以便下次使用它。
请在下面找到我的示例:
const [redirect, setRedirect] = useState(false);
const handleRedirect = useCallback(() => {
let render = null;
if (redirect) {
render = <Redirect to="/redirectpush" push={true} />
// In order wait until committing to the DOM
// and get back the button for clicking next time
setTimeout(() => setRedirect(false), 0);
}
return render;
}, [redirect]);
return <>
{handleRedirect()}
<button onClick={() => setRedirect(true)}>
Redirect push
</button>
</>
Run Code Online (Sandbox Code Playgroud)
从<Redirect>
文档:
渲染 a
<Redirect>
将导航到新位置。新位置将覆盖历史堆栈中的当前位置,就像服务器端重定向 (HTTP 3xx) 那样。
useHistory
钩子:在我的解决方案中有一个名为的组件UseHistoryAction
,它代表以下内容:
let history = useHistory();
return <button onClick={() => { history.push('/usehistory') }}>
useHistory redirect
</button>
Run Code Online (Sandbox Code Playgroud)
该
useHistory
钩让我们访问历史记录对象,这有助于我们编程导航或更改路线。
withRouter
,history
从props
:创建了一个名为 的组件WithRouterAction
,显示如下:
const WithRouterAction = (props:any) => {
const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>
withRouter redirect
</button>
}
export default withRouter(WithRouterAction);
Run Code Online (Sandbox Code Playgroud)
从withRouter
文档中读取:
您可以通过高阶组件访问
history
对象的属性和最接近<Route>
的匹配项withRouter
。每当它呈现时,withRouter
都会将 updatedmatch
、location
和history
props 传递给包装的组件。
演示:
为了更好地表达,我用这些示例构建了一个 GitHub 存储库,请在下面找到它:
归档时间: |
|
查看次数: |
634613 次 |
最近记录: |