Sotero
Sotero

Reputation: 23

Simple On/Off Toggle Component not working

I've have a simple toggle component in react that im quite not sure why it will not work. Also if im using arrow function do I still have to bind(this)?

class MyComponent extends React.Component {
  construtor(props){
    super(props);
    this.state = {visibility: false};
  }

  toggleVisibility = () => {
    this.setState({
      visibility: !this.state.visibility
    });
  }

  render() {
    if(this.state.visibility) {
      return (
        <div>
          <button 
            onClick={this.toggleVisibility}>Click</button>
          <h1>now you see me</h1>
        </div>
      );
    } else {
      return(
      <div>
       <button 
         onClick={this.toggleVisibility}>Click</button>
      </div>
      );
    }
  }
};

ReactDOM.render(<MyComponent />, document.getElementById("root"));

Upvotes: 2

Views: 1120

Answers (2)

jered
jered

Reputation: 11581

I would make two changes. Firstly, you can't define functions on your component as arrow functions like that. That's probably why it's not working. (Yes, that does mean you will need to bind() the function in your constructor.) Secondly, I would refactor your render to conditionally display your <h1> tag only, instead of the entire component.

class MyComponent extends React.Component {
  constructor(props){
    super(props);
    this.state = {visibility: false};
    this.toggleVisibility = this.toggleVisibility.bind(this);
  }

  toggleVisibility() {
    this.setState({
      visibility: !this.state.visibility
    });
  }

  render() {
      return (
        <div>
          <button 
            onClick={this.toggleVisibility}
          >Click</button>
          {this.state.visibility ? <h1>now you see me</h1> : []}
        </div>
      );
  }
};

ReactDOM.render(<MyComponent />, document.getElementById("root"));

Note this part: {this.state.visibility ? <h1>now you see me</h1> : []}. This is an inlined ternary conditional. It's a very common way to either show or hide something in JSX depending on a simple boolean. Use curly braces {} to embed an expression in your JSX, inside of which a ternary conditional will return either one result or another. React will not render empty arrays like [] as anything at all, making it handy for when you want to NOT render a thing.

Ternary operator conditionals look like this: someBoolean ? resultIfTrue : resultIfFalse.

Edit: Also, constructor is misspelled, good catch @RyanHarvey.

Upvotes: 0

Ryan Harvey
Ryan Harvey

Reputation: 88

You have a typo. Constructor, not construtor.

constructor(props){
  super(props);
  this.state = {visibility: false};
}

It works fine with that typo fixed.

Upvotes: 1

Related Questions