简体   繁体   English

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

[英]How to update component's state after redirect?

I'm creating a component that renders a page which includes a dropdown menu. 我正在创建一个呈现包含下拉菜单的页面的组件。 When the user selects an option on the menu, I want him to be redirected to the selected page. 当用户在菜单上选择一个选项时,我希望他被重定向到所选页面。

The code below works, meaning that the user is in fact redirected, but as soon as the new page is rendered I get the following error: 下面的代码有效,这意味着实际上已经重定向了用户,但是一旦呈现了新页面,我就会收到以下错误:

Warning: You tried to redirect to the same route you're currently on. 警告:您试图重定向到当前所在的路线。

Here's my component: 这是我的组件:

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>
        );
    }

}

I believe the problem is that the state in constructor doesn't update when the component re-renders, so redirect still evaluates to true and the app tries to redirect again. 我相信问题在于,当组件重新渲染时, constructor中的状态不会更新,因此redirect仍会评估为true,应用会尝试再次重定向。

So the question is: how do I set redirect to false once the component re-rendered? 所以问题是:重新渲染组件后,如何将redirect设置为false I tried updating the state in methods like componentDidMount , componentWillMount , etc. but they all produce errors of their own... 我尝试通过componentDidMountcomponentWillMount等方法更新状态,但是它们都会产生自己的错误...

There is a static method in life cycle called getDerivedStateFromProps(nextProps, prevState) , I used to componentWillReceiveProps() in old time, but it will be deprecated, you can have more information in doc . 生命周期中有一个静态方法称为getDerivedStateFromProps(nextProps, prevState) ,我过去曾经使用componentWillReceiveProps() ,但是将不建议使用,您可以在doc中获取更多信息。

In your case, It seems UserPage is like a template and taking this.props.match.params.slug as parameter to render different content. 在您的情况下,似乎UserPage就像模板,并以this.props.match.params.slug作为参数来呈现不同的内容。 The problem here is when this component be mounted, React only check difference to re-render it but not re-mount it, you need getDerivedStateFromProps() to detect the new props coming and set new state. 这里的问题是,当安装该组件时,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>
        );
    }

}

This could also work if you're using an older version of react: 如果您使用的是旧版本的react,这也可能会起作用:

componentDidUpdate () {
    if (this.state.redirect) {
        this.setState({
            redirect: false
        })
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM