使用react router,我可以使用Link元素来创建由react route本地处理的链接。
我看到它在内部调用this.context.transitionTo(…)。
我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?
我看到了导航混合,但我可以在没有混合的情况下这样做吗?
使用react router,我可以使用Link元素来创建由react route本地处理的链接。
我看到它在内部调用this.context.transitionTo(…)。
我想做导航。不是来自链接,而是来自下拉选择(例如)。我如何在代码中执行此操作?this.context是什么?
我看到了导航混合,但我可以在没有混合的情况下这样做吗?
当前回答
要将withRouter与基于类的组件一起使用,请尝试以下操作。不要忘记将导出语句更改为与Router一起使用:
从“react router dom”导入{withRouter}
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);
其他回答
在我的回答中,有三种不同的方法可以通过编程重定向到路由。已经介绍了一些解决方案,但下面的解决方案仅针对具有附加演示应用程序的功能组件。
使用以下版本:
反应: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>
从有关<HashRouter>的文档中:
一个<Router>,它使用URL的哈希部分(即window.location.hash)来保持UI与URL同步。
解决:
使用<Redirect>使用useState推送:
在功能组件(我的存储库中的RedirectPushAction组件)中使用,我们可以使用useState来处理重定向。棘手的是,一旦发生重定向,我们需要将重定向状态设置回false。通过使用带有0延迟的setTimeOut,我们等待React提交重定向到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>
</>
从<Redirect>文档:
渲染<重定向>将导航到新位置。新位置将覆盖历史堆栈中的当前位置,就像服务器端重定向(HTTP 3xx)那样。
使用useHistory钩子:
在我的解决方案中,有一个名为UseHistoryAction的组件,它表示以下内容:
let history = useHistory();
return <button onClick={() => { history.push('/usehistory') }}>
useHistory redirect
</button>
useHistory钩子允许我们访问历史对象,它帮助我们以编程方式导航或更改路线。
使用withRouter,从道具获取历史记录:
创建了一个名为WithRouterAction的组件,显示如下:
const WithRouterAction = (props:any) => {
const { history } = props;
return <button onClick={() => { history.push('/withrouter') }}>
withRouter redirect
</button>
}
export default withRouter(WithRouterAction);
阅读路由器文档:
您可以通过withRouter高阶组件访问历史对象的财产和最接近的<Route>匹配项。无论何时渲染,withRouter都会将更新的匹配、位置和历史属性传递给包装组件。
演示:
为了更好地表示,我用这些示例构建了一个GitHub存储库,请在下面找到它:
React Router程序化重定向示例
React路由器v2
对于最新版本(v2.0.0-rc5),推荐的导航方法是直接推到历史单例。您可以在组件外部导航文档中看到这一点。
相关摘录:
import { browserHistory } from 'react-router';
browserHistory.push('/some/path');
如果使用更新的react router API,则需要在组件内部使用this.props中的历史记录,以便:
this.props.history.push('/some/path');
它还提供pushState,但对于每个记录的警告,它都是不推荐的。
如果使用react router redux,它提供了一个推送功能,您可以这样调度:
import { push } from 'react-router-redux';
this.props.dispatch(push('/some/path'));
然而,这可能仅用于更改URL,而不是实际导航到页面。
如果您碰巧通过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)
如果您使用redux thunk/saga来管理异步流,请在redux操作中导入上述操作创建者,并使用mapDispatchToProps连接到React组件可能会更好。
要以编程方式进行导航,您需要将新的历史推送到组件中的props.history,这样就可以完成以下工作:
//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;
在基于类的组件中编程导航。
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}/>
}
.....
.....
}
}