Richard
Richard

Reputation: 16812

What is the React.js way of handling visibility=hidden?

React does not support the visibility attribute for elements.

So if I want to show or hide an element on the page, but still have it take up space when hidden so the layout doesn't shift, how do I do something like this?

<i className="fa fa-trash" visibility={this.state.showButton ? "visible": "hidden"} />

Upvotes: 32

Views: 90429

Answers (10)

Sergio Holgado
Sergio Holgado

Reputation: 33

Simply use useState to change the component through an if statement inside the function component, this way the pop up will change dynamically since every time the state is change the page is rendered.

import {useState} from 'react'

function App(){
    
   const [visible, setvisible] = useState(false); //false => hidden (initial state)
    
   function Fafatrash(){
      if(visible === true){
        return(
            <div className="fa fa-trash">
            </div>
            )}
      else{
        return(
                <div></div>
              )
            }
          }
      return(
       <Fafatrash/>
      );
    }

Upvotes: 0

Jack
Jack

Reputation: 951

Or just use the ternary operator:

{
!this.state.showButton ? null :
<i className="fa fa-trash"/>
}

Upvotes: 0

Stan
Stan

Reputation: 104

Solution with using style attribute and TypeScript:

import React, { CSSProperties } from 'react';

...
const style: CSSProperties = {
    visibility: this.state.showButton ? 'visible': 'hidden',
  };

const someJSXElement = (
    <i className="fa fa-trash" style={style} />
);

I suppose in vanilla JS you don't need to typecast:

import React from 'react';

...
const style = {
    visibility: this.state.showButton ? 'visible': 'hidden',
  };

const someJSXElement = (
    <i className="fa fa-trash" style={style} />
);

Or a shortway:

<i className="fa fa-trash" style={{ visibility: this.state.showButton ? 'visible': 'hidden' }} />

Upvotes: 3

Emilio Rodriguez
Emilio Rodriguez

Reputation: 5749

You can use a CSS class for that and dynamically modify your className. For example:

<i className={this.state.showButton ? "fa fa-trash" : "fa fa-trash hidden"} />

Upvotes: 22

Matt
Matt

Reputation: 1558

What is your use case? Do you want to...

  1. remove and add the component from the DOM?
  2. use CSS to hide or show the component? The component is always in the DOM
  3. re-render a new component. This causes the DOM to re-render.

Use component to state to manage the show hide effect.

class ExampleShowHide extends React.Component {
    constructor(props) {
       super(props);
           this.state = {
               show: false, 
           };
        this.toggleShowHide = this.toggleShowHide.bind(this);
     }

    toggleShowHide() {
        this.setState(oldState => ({show: !oldState.show}));
    }

    render() {
        return(<>
            <a onClick={() => this.toggleShowHide()}> Toggle </a>
        </>)
    }
}

The above will toggle the state prop 'show' from true and false. Now you have three options. All three options are done in render()

  1. Let's have the toggle completely remove and add a component from the DOM.
    { this.state.show && <MyComponent /> }
  1. Let's keep the component in the DOM but hide and show using CSS.
    <div style={{
       visibility: this.state.showCreditCardFrom ? "visible" : "hidden",
    }}>
        <MyComponent />
   </div>
  1. Let's cause a complete re-render
    render() {
        if(this.state.show) {
            return <MyComponent />
        } else {
            return <></>
        }
    }

Upvotes: 3

noone
noone

Reputation: 6568

Or you can just do it like this in your react component

{
   this.state.showButton && <i className="fa fa-trash"  />
}

// Get a hook function
const {useState} = React;

const Example = ({title}) => {
  const [visible, setVisible] = useState(false);

  return (
    <div>
      <p>{title}</p>
      
      <button onClick={() => setVisible(!visible)}>
        visibility : {!visible ? "hidden" : "showing"}
      </button>
      {visible && <p>Its toggling visibility</p>}
    </div>
  );
};

// Render it
ReactDOM.render(
  <Example title="Example using Hooks:" />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Upvotes: 2

Craig Curtis
Craig Curtis

Reputation: 863

You could use string interpolation to add a css class:

<i className={`fa fa-trash ${this.state.showButton ? "" : "hidden"}`} />

Upvotes: 1

gandreadis
gandreadis

Reputation: 3242

While the accepted answer works perfectly, I want to mention the classnames NPM package as an alternative way of implementing it in a more DRY-friendly way. With that package, you don't need to copy the other, static classes between two strings:

<i className={classNames("fa", "fa-trash", {"hidden": !this.state.showButton})} />

Upvotes: 1

David Xu
David Xu

Reputation: 5597

You can use CSS for this.

<i className="fa fa-trash" style={{visibility: this.state.showButton ? 'visible' : 'hidden' }} />

Learn more about inline styles in React

Upvotes: 38

Slowyn
Slowyn

Reputation: 8843

This is a css-attribute so you can use inline-styles:

...
var visibilityState = this.state.showButton ? "visible" : "hidden";
return (
  <i className="fa fa-trash" style={{visibility: visibilityState}}/>
);
...

Upvotes: 5

Related Questions