Show or hide element in React

I am messing around with React.js for the first time and cannot find a way to show or hide something on a page via click event. I am not loading any other library to the page, so I am looking for some native way using the React library. This is what I have so far. I would like to show the results div when the click event fires.

var Search= React.createClass({
    handleClick: function (event) {
        console.log(this.prop);
    },
    render: function () {
        return (
            <div className="date-range">
                <input type="submit" value="Search" onClick={this.handleClick} />
            </div>
        );
    }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);

Answers:

Answer

The key is to update the state of the component in the click handler using setState. When the state changes get applied, the render method gets called again with the new state:

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle

Answer

Here is an alternative syntax for the ternary operator:

{ this.state.showMyComponent ? <MyComponent /> : null }

is equivalent to:

{ this.state.showMyComponent && <MyComponent /> }

Lean why


Also alternative syntax with display: 'none';

<MyComponent style={this.state.showMyComponent ? {} : { display: 'none' }} />

However, if you overuse display: 'none', this leads to DOM pollution and ultimately slows down your application.

Answer

with the newest version react 0.11 you can also just return null to have no content rendered.

Rendering to null

Answer

I created a small component that handles this for you: react-toggle-display

It sets the style attribute to display: none !important based on the hide or show props.

Example usage:

var ToggleDisplay = require('react-toggle-display');

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                <ToggleDisplay show={this.state.showResults}>
                    <Results />
                </ToggleDisplay>
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search />, document.body);
Answer

This is a nice way to make use of the virtual DOM:

class Toggle extends React.Component {
  state = {
    show: true,
  }

  toggle = () => this.setState((currentState) => ({show: !currentState.show}));

  render() {
    return (
      <div>
        <button onClick={this.toggle}>
          toggle: {this.state.show ? 'show' : 'hide'}
        </button>    
        {this.state.show && <div>Hi there</div>}
      </div>
     );
  }
}

Example here

Using React hooks:

const Toggle = () => {
  const [show, toggleShow] = React.useState(true);

  return (
    <div>
      <button
        onClick={() => toggleShow(!show)}
      >
        toggle: {show ? 'show' : 'hide'}
      </button>    
      {show && <div>Hi there</div>}
    </div>
  )
}

Example here

Answer

You set a boolean value in the state (e.g. 'show)', and then do:

var style = {};
if (!this.state.show) {
  style.display = 'none'
}

return <div style={style}>...</div>
Answer

Best practice is below according to the documentation:

{this.state.showFooter && <Footer />}

Render the element only when the state is valid.

Answer

I start with this statement from the React team:

In React, you can create distinct components that encapsulate behaviour you need. Then, you can render only some of them, depending on the state of your application.

Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like if or the conditional operator to create elements representing the current state, and let React update the UI to match them.

You basically need to show the component when the button gets clicked, you can do it two ways, using pure React or using CSS, using pure React way, you can do something like below code in your case, so in the first run, results are not showing as hideResults is true, but by clicking on the button, state gonna change and hideResults is false and the component get rendered again with the new value conditions, this is very common use of changing component view in React...

var Search = React.createClass({
  getInitialState: function() {
    return { hideResults: true };
  },

  handleClick: function() {
    this.setState({ hideResults: false });
  },

  render: function() {
    return (
      <div>
        <input type="submit" value="Search" onClick={this.handleClick} />
        { !this.state.hideResults && <Results /> }
      </div> );
  }

});

var Results = React.createClass({
  render: function() {
    return (
    <div id="results" className="search-results">
      Some Results
    </div>);
   }
});

ReactDOM.render(<Search />, document.body);

If you want to do further study in conditional rendering in React, have a look here.

Answer
class Toggle extends React.Component {
  state = {
    show: true,
  }

  render() {
    const {show} = this.state;
    return (
      <div>
        <button onClick={()=> this.setState({show: !show })}>
          toggle: {show ? 'show' : 'hide'}
        </button>    
        {show && <div>Hi there</div>}
      </div>
     );
  }
}
Answer
   class FormPage extends React.Component{
      constructor(props){
           super(props);
           this.state = {
             hidediv: false
           }
      }

     handleClick = (){
       this.setState({
          hidediv: true
        });
      }

      render(){
        return(
        <div>
          <div className="date-range" hidden = {this.state.hidediv}>
               <input type="submit" value="Search" onClick={this.handleClick} />
          </div>
          <div id="results" className="search-results" hidden = {!this.state.hidediv}>
                        Some Results
           </div>
        </div>
        );
      }
  }
Answer

In some cases higher order component might be useful:

Create higher order component:

export var HidableComponent = (ComposedComponent) => class extends React.Component {
    render() {
        if ((this.props.shouldHide!=null && this.props.shouldHide()) || this.props.hidden)
            return null;
        return <ComposedComponent {...this.props}  />;
    }
};

Extend your own component:

export const MyComp= HidableComponent(MyCompBasic);

Then you can use it like this:

<MyComp hidden={true} ... />
<MyComp shouldHide={this.props.useSomeFunctionHere} ... />

This reduces a bit boilerplate and enforces sticking to naming conventions, however please be aware of that MyComp will still be instantiated - the way to omit is was mentioned earlier:

{ !hidden && <MyComp ... /> }

Answer

A simple method to show/hide elements in React using Hooks

const [showText, setShowText] = useState(false);

Now, let's add some logic to our render method:

{showText && <div>This text will show!</div>}

And

onClick={() => setShowText(!showText)}

Good job.

Answer

If you use bootstrap 4, you can hide element that way

className={this.state.hideElement ? "invisible" : "visible"}
Answer

This can also be achieved like this (very easy way)

 class app extends Component {
   state = {
     show: false
   };
 toggle= () => {
   var res = this.state.show;
   this.setState({ show: !res });
 };
render() {
  return(
   <button onClick={ this.toggle }> Toggle </button>
  {
    this.state.show ? (<div> HELLO </div>) : null
  }
   );
     }
Answer

this example shows how you can switch between components by using a toggle which switches after every 1sec

import React ,{Fragment,Component} from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Component1 = () =>(
  <div>
    <img 
src="https://i.pinimg.com/originals/58/df/1d/58df1d8bf372ade04781b8d4b2549ee6.jpg" />
   </div>
)

const Component2 = () => {
  return (
    <div>
       <img 
src="http://www.chinabuddhismencyclopedia.com/en/images/thumb/2/2e/12ccse.jpg/250px- 
12ccse.jpg" />
  </div>
   )

 }

 class App extends Component {
   constructor(props) {
     super(props);
    this.state = { 
      toggleFlag:false
     }
   }
   timer=()=> {
    this.setState({toggleFlag:!this.state.toggleFlag})
  }
  componentDidMount() {
    setInterval(this.timer, 1000);
   }
  render(){
     let { toggleFlag} = this.state
    return (
      <Fragment>
        {toggleFlag ? <Component1 /> : <Component2 />}
       </Fragment>
    )
  }
}


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Answer

Use this lean and short syntax:

{ this.state.show && <MyCustomComponent /> }
Answer

Here comes the simple, effective and best solution with a Classless React Component for show/hide the elements. Use of React-Hooks which is available in the latest create-react-app project that uses React 16

import React, {useState} from 'react';
function RenderPara(){
const [showDetail,setShowDetail] = useState(false);

const handleToggle = () => setShowDetail(!showDetail);

return (
<React.Fragment>
    <h3>
        Hiding some stuffs 
    </h3>
    <button onClick={handleToggle}>Toggle View</button>
   {showDetail && <p>
        There are lot of other stuffs too
    </p>}
</React.Fragment>)

}  
export default RenderPara;

Happy Coding :)

Answer
//use ternary condition

{ this.state.yourState ? <MyComponent /> : null } 

{ this.state.yourState && <MyComponent /> }

{ this.state.yourState == 'string' ? <MyComponent /> : ''}

{ this.state.yourState == 'string' && <MyComponent /> }

//Normal condition

if(this.state.yourState){
 return <MyComponent />
}else{
  return null;
}
Answer

Simple hide/show example with React Hooks: (srry about no fiddle)

const Example = () => {

  const [show, setShow] = useState(false);

  return (
    <div>
      <p>Show state: {show}</p>
      {show == true ? (
        <p>You can see me!</p>
      ) : null}
      <button onClick={() => setShow(!show)}>
    </div>
  );

};

export default Example;
Answer

You can use the css file

    var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className={`search-results ${this.state.showResults ? 'show' : ''}`}>
                Some Results
            </div>
        );
    }
})

and in the css file

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}
Answer
var Search= React.createClass({
 getInitialState: () => { showResults: false },
 onClick: () => this.setState({ showResults: true }),
 render: function () {
   const { showResults } = this.state;
   return (
     <div className="date-range">
       <input type="submit" value="Search" onClick={this.handleClick} />
       {showResults && <Results />}
     </div>
   );
 }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);
Answer
class App extends React.Component {
  state = {
    show: true
  };

  showhide = () => {
    this.setState({ show: !this.state.show });
  };

  render() {
    return (
      <div className="App">
        {this.state.show && 
          <img src={logo} className="App-logo" alt="logo" />
        }
        <a onClick={this.showhide}>Show Hide</a>
      </div>
    );
  }
}
Answer
<style type="text/css">
    .hidden { display:none; }
</style>
render: function() {
    return (
      <div className={this.props.shouldHide ? 'hidden' : ''}>
        This will be hidden if you set <tt>props.shouldHide</tt> 
        to something truthy.
      </div>
    );
}

// or in more modern JS and stateless react
const Example = props => <div className={props.shouldHide}/>Hello</div>
Answer

Here is my approach using ES6. While accepted answer is correct, it's quite outdated.

import React, { Component } from 'react';
// you should use ReactDOM.render instad of React.renderComponent
import ReactDOM from 'react-dom';

class ToggleBox extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // toggle box is closed initially
      isOpened: false,
    };
    // http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html
    this.toggleBox = this.toggleBox.bind(this);
  }

  toggleBox() {
    this.setState(oldState => ({ isOpened: !oldState.isOpened }));
  }

  render() {
    const { title, children } = this.props;
    const { isOpened } = this.state;
    return (
      <div className="box">
        <div className="boxTitle" onClick={this.toggleBox}>
          {title}
        </div>
        {isOpened && children && (
          <div className="boxContent">
            {children}
          </div>
        )}
      </div>
    );
  }
}

ReactDOM.render((
  <ToggleBox title="Click me">
    <div>Some content</div>
  </ToggleBox>
), document.getElementById('app'));

Demo: http://jsfiddle.net/kb3gN/16688/

It's better to render some element only if needed rather than adding some css classes with display: none. If you set display: none - element is still rendered by react and added to DOM - that can have bad impact on performance.

Imagine you have page with tabs, where every tab have a lot of content and where only 1 tab is opened at once. It's much better to hold in the DOM only those elements that are supposed to be displayed.

In code above, to achieve this, I'm using code like:

{opened && <SomeElement />}

That will render SomeElement only if opened is true. It works because of the way how JavaScript resolve logical conditions:

true && true && 2; // will output 2
true && false && 2; // will output false
true && 'some string'; // will output 'some string'
opened && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise
Answer

There are several great answers already, but I don't think they've been explained very well and several of the methods given contain some gotchas that might trip people up. So I'm going to go over the three main ways (plus one off-topic option) to do this and explain the pros and cons. I'm mostly writing this because Option 1 was recommended a lot and there's a lot of potential issues with that option if not used correctly.

Option 1: Conditional Rendering in the parent.

I don't like this method unless you're only going to render the component one time and leave it there. The issue is it will cause react to create the component from scratch every time you toggle the visibility. Here's the example. LogoutButton or LoginButton are being conditionally rendered in the parent LoginControl. If you run this you'll notice the constructor is getting called on each button click. https://codepen.io/Kelnor/pen/LzPdpN?editors=1111

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;

    let button = null;
    if (isLoggedIn) {
      button = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Now React is pretty quick at creating components from scratch. However, it still has to call your code when creating it. So if your constructor, componentDidMount, render, etc code is expensive, then it'll significantly slow down showing the component. It also means you cannot use this with stateful components where you want the state to be preserved when hidden (and restored when displayed.) The one advantage is that the hidden component isn't created at all until it's selected. So hidden components won't delay your initial page load. There may also be cases where you WANT a stateful component to reset when toggled. In which case this is your best option.

Option 2: Conditional Rendering in the child

This creates both components once. Then short circuits the rest of the render code if the component is hidden. You can also short circuit other logic in other methods using the visible prop. Notice the console.log in the codepen page. https://codepen.io/Kelnor/pen/YrKaWZ?editors=0011

class LoginControl extends React.Component {
  constructor(props) {
    super(props);
    this.handleLoginClick = this.handleLoginClick.bind(this);
    this.handleLogoutClick = this.handleLogoutClick.bind(this);
    this.state = {isLoggedIn: false};
  }

  handleLoginClick() {
    this.setState({isLoggedIn: true});
  }

  handleLogoutClick() {
    this.setState({isLoggedIn: false});
  }

  render() {
    const isLoggedIn = this.state.isLoggedIn;
    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        <LoginButton isLoggedIn={isLoggedIn} onClick={this.handleLoginClick}/>
        <LogoutButton isLoggedIn={isLoggedIn} onClick={this.handleLogoutClick}/>
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    if(!this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    if(this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Now, if the initialization logic is quick and the children are stateless, then you won't see a difference in performance or functionality. However, why make React create a brand new component every toggle anyway? If the initialization is expensive however, Option 1 will run it every time you toggle a component which will slow the page down when switching. Option 2 will run all of the component's inits on first page load. Slowing down that first load. Should note again. If you're just showing the component one time based on a condition and not toggling it, or you want it to reset when toggledm, then Option 1 is fine and probably the best option.

If slow page load is a problem however, it means you've got expensive code in a lifecycle method and that's generally not a good idea. You can, and probably should, solve the slow page load by moving the expensive code out of the lifecycle methods. Move it to an async function that's kicked off by ComponentDidMount and have the callback put it in a state variable with setState(). If the state variable is null and the component is visible then have the render function return a placeholder. Otherwise render the data. That way the page will load quickly and populate the tabs as they load. You can also move the logic into the parent and push the results to the children as props. That way you can prioritize which tabs get loaded first. Or cache the results and only run the logic the first time a component is shown.

Option 3: Class Hiding

Class hiding is probably the easiest to implement. As mentioned you just create a CSS class with display: none and assign the class based on prop. The downside is the entire code of every hidden component is called and all hidden components are attached to the DOM. (Option 1 doesn't create the hidden components at all. And Option 2 short circuits unnecessary code when the component is hidden and removes the component from the DOM completely.) It appears this is faster at toggling visibility according some tests done by commenters on other answers but I can't speak to that.

Option 4: One component but change Props. Or maybe no component at all and cache HTML.

This one won't work for every application and it's off topic because it's not about hiding components, but it might be a better solution for some use cases than hiding. Let's say you have tabs. It might be possible to write one React Component and just use the props to change what's displayed in the tab. You could also save the JSX to state variables and use a prop to decide which JSX to return in the render function. If the JSX has to be generated then do it and cache it in the parent and send the correct one as a prop. Or generate in the child and cache it in the child's state and use props to select the active one.

Answer

If you would like to see how to TOGGLE the display of a component checkout this fiddle.

http://jsfiddle.net/mnoster/kb3gN/16387/

var Search = React.createClass({
    getInitialState: function() {
        return { 
            shouldHide:false
        };
    },
    onClick: function() {
        console.log("onclick");
        if(!this.state.shouldHide){
            this.setState({
                shouldHide: true 
            })
        }else{
                    this.setState({
                shouldHide: false 
            })
        }
    },
render: function() {
    return (
      <div>
        <button onClick={this.onClick}>click me</button>
        <p className={this.state.shouldHide ? 'hidden' : ''} >yoyoyoyoyo</p>
      </div>
    );
}
});

ReactDOM.render( <Search /> , document.getElementById('container'));
Answer

Use rc-if-else module

npm install --save rc-if-else
import React from 'react';
import { If } from 'rc-if-else';

class App extends React.Component {
    render() {
        return (
            <If condition={this.props.showResult}>
                Some Results
            </If>
        );
    }
}
Answer

Use ref and manipulate CSS

One way could be to use React's ref and manipulate CSS class using the browser's API. Its benefit is to avoid rerendering in React if the sole purpose is to hide/show some DOM element on the click of a button.

// Parent.jsx
import React, { Component } from 'react'

export default class Parent extends Component {
    constructor () {    
        this.childContainer = React.createRef()
    }

    toggleChild = () => {
        this.childContainer.current.classList.toggle('hidden')
    }

    render () {
        return (
            ...

            <button onClick={this.toggleChild}>Toggle Child</button>
            <div ref={this.childContainer}>
                <SomeChildComponent/>
            </div>

            ...
        );
    }
}


// styles.css
.hidden {
    display: none;
}

PS Correct me if I am wrong. :)

Answer

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="checkbox" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                <input type="text" />
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.