Home > Blockchain >  Show/Hide React Component based on State
Show/Hide React Component based on State

Time:10-22

I am very new to React and am trying to create a page where clicking on the color square will show the hex code for that color. I've tried a bunch of different things and I can't figure out if my problem is in the event handling, in the state handling, both, or in something else altogether. I can get the hex code to either be there or not, but not have it change when I click.

Here is my main:

    <main>
  <h1>Dynamic Hex Code Display</h1>
  <div id="container"></div>

  <script type="text/babel">
    class ColorSquare extends React.Component {
      render() {
        var blockStyle = {
          height: 150,
          backgroundColor: this.props.color,
        };
        return <div style={blockStyle} onClick = {this.props.onClick}></div>;
      }
    }

    class HexDisplay extends React.Component {
      render() {
        var hexText = {
          fontFamily: "arial",
          fontWeight: "bold",
          padding: 15,
          margin: 0,
          textAlign: "center",
        };

        var hexTextVis = {
          ...hexText,
          visibility: "visible"
        }

        var hexTextInvis = {
          ...hexText,
          visibility: "hidden"
        }

        var isVisible = this.props.isVisible;

        if (isVisible) {
          return <p style={hexTextVis}>{this.props.color}</p>;
        } else {
        return <p style={hexTextInvis}>{this.props.color}</p>;
        }
      }
    }

    class HexParent extends React.Component {
      constructor(props) {
        super(props);

        this.state = {
          isVisible: false
        };

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

      handleClick(e) {
        this.setState(currentVis => ({isVisible: !currentVis.isVisible}));
        console.log(this.state);
        console.log('clicking');
      }

      render() {
        var fullBoxStyle = {
          padding: 0,
          margin: 10,
          backgroundColor: "#fff",
          boxShadow: "3px 3px 5px #808080",
          boxRadius: "5px 5px",
          height: 200,
          width: 150,
        };
        var buttonStyle = {
          width:150,
          backgroundColor: this.props.color
        }

        return (
          <div style={fullBoxStyle}>
            <span onClick={(e) => this.handleClick()}>
              <ColorSquare color={this.props.color} />  
              <span style={{
                isVisible: this.state.isVisible ? "true" : "false",
              }}>                        
              <HexDisplay color={this.props.color} />
              </span>
            </span>   
            
          </div>
        );
      }
    }

    ReactDOM.render(
      <div >
        <HexParent color="#ba2c9d" />
        <HexParent color="#2cba90" />
        <HexParent color="#2c9dba" />
      </div>,
      document.querySelector("#container")
    );
  </script>

CodePudding user response:

When the object is created, it's a hexTextVis object. When you click, isVisible changes, but it's still a hexTextVis object and so the render doesn't change. You could either do something like:

<HexDisplay visibility={state.isVisible}/>

or

{state.isVisible ? <div/> : <HexDisplay />}

CodePudding user response:

style={{
  isVisible: this.state.isVisible ? "true" : "false",
}}

There isn't a css property with this name. Perhaps you meant to use visibility?

style={{
  visibility: this.state.isVisible ? "visible" : "hidden"
}}

CodePudding user response:

Try wrapping the span and and using a ternary operator to render the span element, based on if the condition of isVisible is equal to true, otherwise it should not return anything

{this.state.isVisible && <span><HexDisplay /></span>}

  • Related