【问题标题】:Getting Warning: Cannot update during an existing state transition inside render收到警告:在渲染内的现有状态转换期间无法更新
【发布时间】:2021-05-15 13:52:02
【问题描述】:

关于这个警告已经有很多问题了,但我不明白为什么我的代码会导致这个警告。只是尝试一个基本的登录屏幕来获得手机号码。如果编号有效,则发送 otp 的操作被调度,用户被导航到另一个屏幕。 注释掉了几行 setState 行,但仍然收到此警告。任何帮助表示赞赏。 代码:

class Login extends Component{
state = {
   phone: '',
   validNumber: ''
 }

 handlePhoneChange(value) {
    var regex = /^0[9786]{1}[0-9]{9}/;   
    this.setState({phone: value, validNumber: ''})  
    if(regex.test(value))
    {
      //this.setState({validNumber: 'true'})
       this.props.sendOtp(value)
     }
     else if(value.length == 11) 
    {
      //    this.setState({validNumber: 'false'})
        } 
    }

    onLoginSuccess(){
        const {loginSuccess} = this.props;
        if(loginSuccess != null && loginSuccess != undefined)
        {
            if(loginSuccess === 'YES')
            {
               // this.resetValues()
                this.props.navigation.navigate('Otp')
            }
        }
    }

    resetValues() {
        this.props.resetResponse()
        // this.setState({
        //      phone: '', 
        //     validNumber: ''
        // });
    }

    render(){
        return (
        <View style={{ flex: 1}} >
                <Input 
                placeholder='Enter Mobile Number'
                keyboardType = 'phone-pad' 
                value = {this.state.phone}
                onChangeText = { (value) => { this.handlePhoneChange(value.replace(/\D/g,'')) } }
                inputStyle = {{fontSize: 14}}
                maxLength = {11}
                rightIcon = { this.state.validNumber === 'true'? 
                            <CustomIcon name = 'Tick' size={25} color = 'green'/> : null}
                errorMessage = {this.state.validNumber === 'false'? 'Please enter a valid number' : ''}
                />
                {this.onLoginSuccess()}
        </View>
        )
    }
}

更新: 警告信息如下

  ERROR    Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
    in LoginScreen (created by ConnectFunction)
    in ConnectFunction (created by SceneView)
    in SceneView (created by CardContainer)
    in RCTView (at View.js:34)
    in View (created by CardContainer)
    in RCTView (at View.js:34)
    in View (created by CardContainer)
    in RCTView (at View.js:34)
    in View (created by ForwardRef(CardSheet))
    in ForwardRef(CardSheet) (created by Card)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (created by PanGestureHandler)
    in PanGestureHandler (created by PanGestureHandler)
    in PanGestureHandler (created by Card)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (created by Card)
    in RCTView (at View.js:34)
    in View (created by Card)
    in Card (created by CardContainer)
    in CardContainer (created by CardStack)
    in RCTView (at View.js:34)
    in View (created by MaybeScreen)
    in MaybeScreen (created by CardStack)
    in RCTView (at View.js:34)
    in View (created by MaybeScreenContainer)
    in MaybeScreenContainer (created by CardStack)
    in CardStack (created by Context.Consumer)
    in KeyboardManager (created by Context.Consumer)
    in RNCSafeAreaProvider (at SafeAreaContext.tsx:74)
    in SafeAreaProvider (created by Context.Consumer)
    in SafeAreaProviderCompat (created by StackView)
    in RCTView (at View.js:34)
    in View (created by StackView)
    in StackView (created by StackView)
    in StackView
    in Unknown (created by Navigator)
    in Navigator (created by NavigationContainer)
    in NavigationContainer (at App.js:22)
    in Provider (at App.js:21)
    in App (at renderApplication.js:45)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:106)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:132)
    in AppContainer (at renderApplication.js:39)

【问题讨论】:

  • 您能确认是哪一行导致触发警告吗?
  • 我是新手,因此无法看到导致此警告的行。让我编辑和更新我的警告
  • 好吧,我们换一种方式试试。如果您在 return 语句中注释掉 this.onLoginSuccess() 会发生什么?我知道您的代码不会重定向您,但警告会消失吗?
  • 是的,警告消失了
  • 我添加了一个答案。如果这能解决您的问题,请告诉我。

标签: reactjs react-native setstate


【解决方案1】:

所以看来你的问题在于你的 fn 调用。 虽然我不知道你在什么时候收到了你的登录道具,但是,你应该做以下事情。

  1. 从返回中删除您的函数调用。

问题在于,每当 React 重新渲染你的组件时,你的函数就会被调用。我可以想象,这是一个问题的一种方式是,如果您已经离开该组件,则调用此函数,但该组件未从堆栈中删除,因此它会在您的导航事件期间尝试重新呈现. 这不是您问题的确切原因,但它可能会触发此类警告。

  1. 将导航移至componentDidUpdate

这样,当你的 props 发生变化时,你的函数只会被调用一次,并且在渲染阶段不会发生导航,因为这个生命周期方法是在你的组件渲染之后调用的。

class Login extends Component{
state = {
   phone: '',
   validNumber: ''
 }

 componentDidUpdate(prevProps) {
   if (!prevProps.loginSuccess && this.props.loginSuccess === "YES") {
     this.props.navigation.navigate('Otp')
   }
 }

    render(){
        return (
        <View style={{ flex: 1}} >
                <Input 
                placeholder='Enter Mobile Number'
                keyboardType = 'phone-pad' 
                value = {this.state.phone}
                onChangeText = { (value) => { this.handlePhoneChange(value.replace(/\D/g,'')) } }
                inputStyle = {{fontSize: 14}}
                maxLength = {11}
                rightIcon = { this.state.validNumber === 'true'? 
                            <CustomIcon name = 'Tick' size={25} color = 'green'/> : null}
                errorMessage = {this.state.validNumber === 'false'? 'Please enter a valid number' : ''}
                />
        </View>
        )
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-31
    • 2017-12-20
    • 1970-01-01
    • 2017-05-16
    • 2016-09-20
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    相关资源
    最近更新 更多