Search code examples
reactjsshow-hide

Show/Hide components in ReactJS


We have been experiencing some problems in using react now but it kinda boils to one part of how we have been using react.

How should we have been showing/hiding child components?

This is how we have coded it (this are only snippets of our components)...

_click: function() {
  if ($('#add-here').is(':empty'))
    React.render(<Child />, $('#add-here')[0]);
  else
    React.unmountComponentAtNode($('#add-here')[0]);
},
render: function() {
  return(
    <div>
      <div onClick={this._click}>Parent - click me to add child</div>
      <div id="add-here"></div>
    </div>
  )
}

and lately I've been reading examples like it should've been somewhere along this lines:

getInitialState: function () {
  return { showChild: false };
},
_click: function() {
  this.setState({showChild: !this.state.showChild});
},
render: function() {
  return(
    <div>
      <div onClick={this._click}>Parent - click me to add child</div>
      {this.state.showChild ? <Child /> : null}
    </div>
  )
}

Should I have been using that React.render()? It seems to stop various things like shouldComponentUpdate to cascade to child and things like e.stopPropagation...


Solution

  • I've provided a working example that follows your second approach. Updating the component's state is the preferred way to show/hide children.

    Given you have this container:

    <div id="container">
    </div>
    

    you can either use modern Javascript (ES6, first example) or classic JavaScript (ES5, second example) to implement the component logic:

    Show/hide components using ES6

    Try this demo live on JSFiddle

    class Child extends React.Component {
      render() {
        return (<div>I'm the child</div>);
      }
    }
    
    class ShowHide extends React.Component {
      constructor() {
        super();
        this.state = {
          childVisible: false
        }
      }
    
      render() {
        return (
          <div>
            <div onClick={() => this.onClick()}>
              Parent - click me to show/hide my child
            </div>
            {
              this.state.childVisible
                ? <Child />
                : null
            }
          </div>
        )
      }
    
      onClick() {
        this.setState(prevState => ({ childVisible: !prevState.childVisible }));
      }
    };
    
    React.render(<ShowHide />, document.getElementById('container'));
    

    Show/hide components using ES5

    Try this demo live on JSFiddle

    var Child = React.createClass({
      render: function() {
        return (<div>I'm the child</div>);
      }
    });
    
    var ShowHide = React.createClass({
      getInitialState: function () {
        return { childVisible: false };
      },
    
      render: function() {
        return (
          <div>
            <div onClick={this.onClick}>
              Parent - click me to show/hide my child
            </div>
            {
              this.state.childVisible
                ? <Child />
                : null
            }
          </div>
        )
      },
    
      onClick: function() {
        this.setState({childVisible: !this.state.childVisible});
      }
    });
    
    React.render(<ShowHide />, document.body);