Ajith
Ajith

Reputation: 845

'Warning: Can\'t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application

im building a react native application ,still i have 2 screens 1.Enter mobile 2.Verify Otp

EnterUserInfo.js

class UserInfoInput extends Component {
    constructor(props) {
    super(props);

    this.state = { formValid:true,
                   validMobileNumber:false,
                   .
                   .}}


   componentWillReceiveProps(nextProps) {
     if(nextProps.common.isFetching===false) {
         this.props.navigation.navigate('VerifyOtpScreen')
         .
         .
       } else {
       this.setState({isLoading:true})
          }} 

  onPressNext=()=> {
         this.props.sendOtp(payload)}

  render() {
    return (<View/>) 
   }
   }


 }
function mapStateToProps(state) {
 return {
    common: state.common
      }
}

function mapDispatchToProps(dispatch) {
  return {
  ...bindActionCreators({ sendOtp }, dispatch)
   }
 }

export default connect(mapStateToProps,mapDispatchToProps)(UserInfoInput);

Here user enter the phone number ,and trigger an action sendOtp,response will be in the reducer and it will be available in the componentwillrecieveprops() lifecycle.

VerifyOtp.js

class VerifyOtp extends Component {

  constructor(props) {
        super(props);
        this.state = { oneTimePIN: '' ,
                      .};
      }

  componentDidMount(){
         this.setState({ phoneNumber:this.props.common.phone});
       }

   componentWillMount() {
      setTimeout(() => {
        this.setState({ isResendDisabled: false, opacity: 1 });
      }, 30000);
    }

  componentWillReceiveProps(nextProps){
  //do operation 
  }

    onPressNext=()=>{
      if(this.state.oneTimePIN=='') {
      this.setState({showNotification:true})
      } 
      else {
        this.onSubmit()
      }
    }

  onSubmit=()=>{
       this.props.verifyOtp(payload) 

     }
 onResendOtp=()=>{

      this.props.sendOtp(payload,locationData) 

      this.setState({ isResendDisabled: true, opacity: 0.5 });
      setTimeout(() => {
        this.setState({ isResendDisabled: false, opacity: 1 });
      }, 30000);

    }

   render() {
        return (<View><Elements></View>)
       }

}
 function mapStateToProps(state) {
     return {
          common: state.common
    }
  }
    function mapDispatchToProps(dispatch) {
      return {
          ...bindActionCreators({ verifyOtp,sendOtp }, dispatch)
      }
    }

  export default connect(mapStateToProps,mapDispatchToProps)(VerifyOtp);
 VerifyOtp screen used to verify the otp.

The problem is,If i move back to enterUserinfo screen and move again to the verifyOtp screen im getting the warning message

'Warning: Can\'t perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application What is the reason for the warning , and how tackle the issue?

Upvotes: 2

Views: 2838

Answers (1)

Syed SaeedulHassan Ali
Syed SaeedulHassan Ali

Reputation: 594

This happens when you call an async function followed by setstate. A simple work around would be like this:

constructor(props) {
  this.state = {
    ...
    this.isCancelled: false
  }
}

componentWillMount() {
  setTimeout(() => {
    !this.state.isCancelled && this.setState({ isResendDisabled: false, 
      opacity: 1 });
  }, 30000);
}

and in componentWillUnmount

componentWillUnmount() {
// setting it true to avoid setState waring since componentWillMount is async
this.state.isCancelled = true;
}

Upvotes: 1

Related Questions