【问题标题】:Infinite loop when triggering redirect from componentDidUpdate using ReactTransitionsGroup使用 ReactTransitionsGroup 从 componentDidUpdate 触发重定向时的无限循环
【发布时间】:2017-05-11 00:59:20
【问题描述】:

我最近实现了 ReactTransitionsGroup 来使用 React Router 为我所有的页面转换设置动画(Velocty 组件只是 ReactTransitionsGroup 的一个包装器,所以在实践中是一样的):

render () {
        return (
            <div className="app-layout">
                <NavBar location={this.props.location} />
                <VelocityTransitionGroup enter={{ animation: 'pageTransitionIn' }} leave={{ animation: 'pageTransitionOut' }}>
                    {React.cloneElement(this.props.children, {
                        key: this.props.location.pathname,
                    })}
                </VelocityTransitionGroup>
                <TimeOutModal />
                <Notifications />
            </div>
        );
    }

在我的注册表单中,我有一个表单组件,一旦注册请求成功响应,道具就会更新,并且该组件将触发重定向到下一个注册步骤。

class SignUp extends Component {

    componentDidUpdate () {
        if (this.props.signup.success) {
            hashHistory.push('/confirm-signup')
        }
    }

    render() {//....//}

}

问题是,一旦触发重定向,我进入一个无限循环,因为 ReactTransitionsGroup 使组件停留几毫秒,再次触发重定向。

我设法“修复”它,在重定向上使用 setTimeout,但我觉得这个解决方案并不优雅:

componentDidUpdate () {
        if (this.props.signup.success) {
            setTimeout(() => {
                hashHistory.push('/confirm-signup')
            }, 500)
        }
    }

您是否找到任何其他解决此问题的方法?

提前致谢!

【问题讨论】:

    标签: javascript reactjs redirect react-router


    【解决方案1】:

    通常我会说在您的表单处理程序中进行重定向。基于signup.success 是一个道具这一事实,我假设您正在使用某种全局存储,并且您必须重写一堆代码才能做到这一点。

    编辑

    您可以将hasTransitioned 属性添加到组件中,您可以在组件转换时设置该属性。

    class Signup extends React.Component {
      hasTransitioned = false
    
      componentDidUpdate() {
        if (this.props.signup.success && !this.hasTransitioned) {
          this.hasTransitioned = true
          hashHistory.push('/confirm-signup')
        }
      }
    }
    

    【讨论】:

    • 感谢您的帮助。我已经测试过这种方法,但无论如何都会触发无限循环。执行push方法后似乎没有立即更改路径,并且每次执行componentDidUpdate时,路径名仍然是'/signup'。
    • 过渡组是否使用先前的道具渲染现有组件?重新匹配是由history 模块在收到新位置时触发的,因此它不应该使用旧位置,除非是这种情况。最好的解决方案可能只是移动到您正在导航的位置。
    • 是的,似乎过渡使用相同的道具更新旧组件,因此 location.pathname 保持相同的值。但总的来说,我想说的是,每次卸载组件时,它都会与新组件的新安装并行更新。
    • 维护现有组件的旧道具是有意义的,这对您来说只是一个问题,因为您的组件有副作用。我用另一种可能的解决方案更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2021-08-26
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 2021-05-07
    • 1970-01-01
    相关资源
    最近更新 更多