简体   繁体   中英

Component not mounted when setState called in arrow function in React with ES2016

Note: I have restructured my question to make it more understandable. However, I have kept the older version for historical purposes.

I have a React application and when I call this.setState() from an arrow function, I get the "component not mounted message". Here is my component:

import React, { Component } from 'react'

class Test extends Component {
    state = {
        value: ''
    }

    onChange = (e) => {
        e.preventDefault()
        this.setState({
            value: e.target.value
        })
    }

    render() {
        return <input value={ this.state.value } onChange={ this.onChange } />
    }
}

When I type into the input, I get the following error message:

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op.

I am not sure why this is, because the arrow function should not have to be binned, and since this is triggered by typing, the component is obviously mounted.

Thanks for any help!


Here is the previous version of this question:

I have a pretty standard React application and when I call this.setState() from an arrow function, I get the "component not mounted message".

The code looks something like this:

 onClick = () => { this.setState({clicked: true}) } ... render() { return <AnotherComponent onClick={ this.onClick } /> } 

When onClick is called, I get this message:

 Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. 

I'm not sure what is causing this, because I am using an arrow function but it is still not working.

EDIT: As asked, here is AnotherComponent :

 const AnotherComponent = (props) => { return ( <div> <Button primary>Reject</Button> <Button primary onClick={ props.onClick }>Edit Post</Button> <Button primary>Approve</Button> </div> ) } 

Thanks

When you say onClick={ this.onClick } you are saying "here is a function to use". However, it loses its context.

You need to bind() the context of onClick() before you pass it into your attribute. The best place to do this is in the constructor of your class.

class MyClass extends React.Component {
     constructor(props) {
       super(props); // have to do this part in any Component constructor
       this.onClick = this.onClick.bind(this);
     }

     onClick() {
       this.setState({ clicked: true });
     }

     render() {
       return <AnotherComponent onClick={ onClick } />;
     }
}

Alternatively, if your function is short, you can just create it in the constructor:

constructor(props) {
  super(props);

  this.onClick = () => { this.setState({ clicked: true }); };
}

By being creating in the context of the constructor, it'll implicitly be bound.

Your component is perfectly correct, now we only have to know where are you calling it from.

This issue usually comes from the parent, just check if the parent is fully mounted.

Matter of fact:

  • onChange doesn't need the e.preventDefault() ,
  • as each time you type on the input, it invokes setting the state ,
  • every time the state gets set,
  • It triggers the lifecycle method render() again ( it reloads the node), so in this case.
  • when you preventDefault() , you're breaking the regular flow of lifecyle components :) remove it and the warning will go away.

====================PART 2 ===========================

Oh I see now, everything is clear :D

Whenever you call the onClick = () => {
    this.setState({clicked: true})
}

...

render() {
    return <AnotherComponent onClick={ this.onClick } />
}

You're wanting to pass down the function through props but you're setting it to the onClick event, and it's a reserved word

You should pass it through a reserved prop like:

return <AnotherComponent handleClick={ this.onClick } />

and then on the child:

<Button primary onClick={ props.handleClick }>Edit Post</Button>

now you created a an actual property

Hope it helped you :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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