8

I have this simple code below. When I press the Toggle Button the component Child should hide/show, but it's not.

Do I have to re-render something? I don't want to switch in/out a CSS class, just toggle via a button click

import React, {Component} from 'react';

let active = true

const handleClick = () => {
    active = !active
}

class Parent extends React.Component {
    render() {      
        return (    
            <div>  
                <OtherComponent />

                {active && <Child />}

                <button type="button" onClick={handleClick}>
                    Toggle
                </button>

            </div>            
        )           
    }
}

class Child extends React.Component {
    render() {

        return (    
            <div>          
                I am the child
            </div>            
        )             
    }
}

class OtherComponent extends React.Component {
    render() {       
        return (    
            <div>          
                I am the OtherComponent
            </div>            
        )           
    }
}
Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
Rory
  • 1,442
  • 4
  • 21
  • 38
  • Possible duplicate of [Show or hide element in React](https://stackoverflow.com/questions/24502898/show-or-hide-element-in-react) – Damjan Pavlica May 08 '18 at 12:02

2 Answers2

7

You need to get or set it via state:

class Parent extends React.Component {
    constructor(props, context) {
        super(props, context);

        this.state = {
            active: true,
        };

        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState({
            active: !this.state.active
        });
    }

    render() {
        return (
            <div>
                <OtherComponent />

                {this.state.active && <Child />}

                <button type="button" onClick={this.handleClick}>
                    Toggle
                </button>

            </div>
        )
    }
}

Note that with this approach you will re:render the entire parent component (as well as it's children).
Consider using another approach, when you are passing a prop to the child component and it will render itself with content based on this prop (it can render an empty div or something).
There are number of libraries that make this job easy for you, like react-collapse with animations and stuff.

Sagiv b.g
  • 30,379
  • 9
  • 68
  • 99
2

You should only use state and props to manage your app state.

So instead try:

class Parent extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
        active: true
    };
    this.handleClick = this.handleClick.bind(this);
  }

  const handleClick = () => {
    this.setState({active = !this.state.active});
  }

  render() {      
    return (    
      <div>  
        <OtherComponent />
        {this.state.active && <Child />}
        <button type="button" onClick={handleClick}>
          Toggle
        </button>
      </div>            
    );          
  }
}

Alernatively, you could use forceUpdate() to force a re-render, but this is strongly discouraged:

const handleClick = () => {
  active = !active;
  this.forceUpdate();
}
Chris
  • 57,622
  • 19
  • 111
  • 137