重定向后如何更新组件的状态?

时间:2018-04-06 07:14:23

标签: javascript reactjs

我正在创建一个呈现包含下拉菜单的页面的组件。当用户在菜单上选择一个选项时,我希望他被重定向到所选页面。

以下代码有效,这意味着用户实际上已重定向,但只要呈现新页面,我就会收到以下错误:

  

警告:您尝试重定向到您当前所在的相同路线。

这是我的组成部分:

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?我尝试在componentDidMountcomponentWillMount等方法中更新状态,但它们都会产生错误......

2 个答案:

答案 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
        })
    }
}