0
class Card extends Component {
  state = {
    toggled: false
  };
  onClick() {
    this.setState({ toggled: !this.state.toggled });
  }
  render() {
    return (
      <div>
        {this.state.toggled && <p>Hello World </p>}
        <button onClick={this.onClick}>Toggle Card</button>
      </div>
    );
  }
}

I have a simple button that toggles a state and renders a <p> tag, I'm getting an error code of

TypeError: Cannot read property 'setState' of undefined

when button is pressed

Vincent Tang
  • 3,758
  • 6
  • 45
  • 63
  • 2
    in your constructor remember to bind your `onClick` -> `this.onClick = this.onClick.bind(this)` – Keith Apr 05 '19 at 14:46
  • doesn't babel implicity handle this behind the scenes? (nevermind, it just creates a constructor but not bind(this)) – Vincent Tang Apr 05 '19 at 14:47
  • @VincentTang nope – AlexZvl Apr 05 '19 at 14:52
  • 1
    @VincentTang No, but you might find this useful. https://www.npmjs.com/package/autobind-decorator Arrow functions like pointed out can be used, but remember an arrow function is like doing a bind every time, for things like `onClick` it's not really an issue, but if you was calling a method multiple times in a loop or wanting to pass the function around ad-hoc, bind might be better. – Keith Apr 05 '19 at 15:13
  • when would you pass a method adhoc in React though? I can see this being useful in vanillaJS though – Vincent Tang Apr 05 '19 at 15:19

1 Answers1

2

You need to bind your function.

Try this:

  onClick = () => {
    this.setState({ toggled: !this.state.toggled });
  }

you need arrow function because you want to access this property, which refers to the current class.

Arrow functions means that this will not refer to the context of your function but to the context of the class.

Another option is to bind your function in constructor

constructor(){
   this.onClick = this.onClick.bind(this);
}
AlexZvl
  • 2,092
  • 4
  • 18
  • 32