我正在创建一个呈现包含下拉菜单的页面的组件。当用户在菜单上选择一个选项时,我希望他被重定向到所选页面。
以下代码有效,这意味着用户实际上已重定向,但只要呈现新页面,我就会收到以下错误:
警告:您尝试重定向到您当前所在的相同路线。
这是我的组成部分:
class UserPage extends React.Component {
constructor( props ) {
super( props );
this.state = {
selectValue: this.props.match.params.slug,
redirect: false
}
}
handleSelectChange( event ) {
this.setState({
selectValue: event.target.value,
redirect: true
});
}
render() {
const redirect = this.state.redirect;
if( redirect ) {
return <Redirect to={ "/you/" + this.state.selectValue } />;
}
return(
<div>
<PageHeader
currentPageSlug={ this.state.currentPageSlug }
selectIntro="You're viewing"
selectOptions={ this.props.menus.userMenu }
selectDefault={ this.state.value }
onSelectChange={ this.handleSelectChange.bind( this ) } />
</div>
);
}
}
我认为问题在于constructor
中的状态在组件重新呈现时没有更新,因此redirect
仍然评估为true,并且应用尝试再次重定向。
所以问题是:一旦组件重新渲染,如何将redirect
设置为false
?我尝试在componentDidMount
,componentWillMount
等方法中更新状态,但它们都会产生错误......
答案 0 :(得分:3)
生命周期中有一个名为getDerivedStateFromProps(nextProps, prevState)
的静态方法,我过去常常使用componentWillReceiveProps()
,但不推荐使用它,您可以在doc中获得更多信息。
在您的情况下,似乎UserPage就像一个模板,并以this.props.match.params.slug
作为参数来呈现不同的内容。这里的问题是当安装这个组件时,React只检查差异以重新渲染它但不重新安装它,你需要getDerivedStateFromProps()
来检测新道具并设置新状态。
class UserPage extends React.Component {
constructor( props ) {
super( props );
}
static getDerivedStateFromProps(nextProps, prevState)
// Below won't work in this method.
// this.setState({
// selectValue: nextProps.match.params.slug,
// redirect: false
// });
//
// We need to return the new state object directly
return {
selectValue: nextProps.match.params.slug,
redirect: false
}
}
handleSelectChange( event ) {
this.setState({
selectValue: event.target.value,
redirect: true
});
}
render() {
const redirect = this.state.redirect;
if( redirect ) {
return <Redirect to={ "/you/" + this.state.selectValue } />;
}
return(
<div>
<PageHeader
currentPageSlug={ this.state.currentPageSlug }
selectIntro="You're viewing"
selectOptions={ this.props.menus.userMenu }
selectDefault={ this.state.value }
onSelectChange={ this.handleSelectChange.bind( this ) } />
</div>
);
}
}
答案 1 :(得分:1)
如果你使用的是旧版本的反应,这也可能有效:
componentDidUpdate () {
if (this.state.redirect) {
this.setState({
redirect: false
})
}
}