【发布时间】:2020-11-28 12:54:07
【问题描述】:
我需要在活动成功后导航到路线。 这似乎比以前的版本有所改变。 以前我们会这样做:
import { browserHistory } from 'react-router';
...
handleClick(){
doSomething();
browserHistory.push('/some/path');
}
【问题讨论】:
标签: javascript reactjs router
我需要在活动成功后导航到路线。 这似乎比以前的版本有所改变。 以前我们会这样做:
import { browserHistory } from 'react-router';
...
handleClick(){
doSomething();
browserHistory.push('/some/path');
}
【问题讨论】:
标签: javascript reactjs router
此示例适用于 react-router 和 react-router-dom v4.0.0。
我们有 3 个组件:
要以编程方式导航,您可以使用 react-router history 对象。
this.props.history.push('path');
对于通过 Route 渲染的组件,这将立即生效,因为这些组件已经可以访问 route props(历史记录)。在我们的示例中,这是 Component2。但是,对于不通过 Route 渲染的组件(例如 Component1),您需要将其包装在 withRouter 中,以便您可以访问 history 对象。
App.js
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import Component1 from './Component1';
import Component2 from './Component2';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Component1 />
<Route path="/render1" render={() => <div>Rendered from Component1</div>} />
<Route path="/" component={Component2} />
<Route path="/render2" render={() => <div>Rendered from Component2</div>} />
</div>
</BrowserRouter>
)
}
}
export default App;
Component1.js
import React from 'react';
import { withRouter } from 'react-router';
class Component1 extends React.Component {
handleButtonClick() {
this.props.history.push('/render1');
}
render() {
return (
<div>
<h1>Component 1</h1>
<button onClick={this.handleButtonClick.bind(this)}>Component 1 Button</button>
</div>
);
}
}
const Component1WithRouter = withRouter(Component1);
export default Component1WithRouter;
对于Component1,我们将其包裹在withRouter中,然后将返回的包裹对象导出。一些问题,请注意在 App.js 中,我们仍然将其引用为 Component1 而不是 Component1WithRouter
Component2.js
import React from 'react';
class Component2 extends React.Component {
handleButtonClick() {
this.props.history.push('/render2');
}
render() {
return (
<div>
<h1>Component 2</h1>
<button onClick={this.handleButtonClick.bind(this)}>Component 2 Button</button>
</div>
);
}
}
export default Component2;
对于 Component2,历史对象已经可以从 this.props 获得。你只需要调用 push 函数。
【讨论】:
如果您使用“函数组件”和 Hooks,而不是期望 props,请改用 useHistory() 函数:
import {useHistory} from 'react-router-dom';
export default function MyFunctionComponent() {
const history = useHistory();
const myEventHandler = () => {
// do stuff
history.push('/newpage');
};
// ...
}
【讨论】:
只需渲染一个redirect 组件:
import { Redirect } from 'react-router';
// ...
<Redirect to="/some/path" />
在此处查看文档:https://reacttraining.com/react-router/core/api/Redirect
【讨论】:
this.setState('successful',true);,然后在我的渲染函数中设置if(this.state.successful) return (<Redirect to="/dogs"/>);,但现在我在事件处理程序中得到“不变违规”。
this.setState({ successful: true })我猜
我非常感谢 CodinCat 的回答,因为他帮助我解决了另一个错误,但我找到了更正确的解决方案:
在 React Router 4.0(我不知道以前的版本)中,路由器将历史对象传递给组件(即:this.props.history)。您可以将您的 url 推送到该数组以重定向:
this.props.history.push('/dogs');
在我的例子中,我有两个级别的组件,路由器称为一个名为 LoginPage 的组件,而 LoginPage 称为一个名为 Login 的组件。如果您将其传递给您的子对象,您只会在它的 props 中拥有历史对象:
<Router>
<Route path="/dogs" component={DogsPage}/>
<Route path="/login" component={LoginPage}/>
</Router>
const LoginPage = (props) => {
// Here I have access to props.history
return (
<div>
<Login history={props.history} />
</div>
)
}
const Login = (props) => {
function handleClick(){
// Now we can simply push our url onto the history and the browser will update
props.history.push('/dogs');
}
return (
<div>
<button onClick={handleClick}>Click to Navigate</button>
</div>
)
}
我知道上面的示例有点做作,因为在这种情况下使用链接会更容易,但我以这种方式制作示例以保持简洁。您可能需要以这种方式导航的原因有很多。就我而言,我正在执行一个 graphQL 请求,并希望在有人成功登录后导航到主页。
【讨论】: