Search code examples
reactjsmaterial-uipopover

Material UI popover not working with react class component


I'm have not used material UI before and all its documentation is with reference with function components. I can not figure out why the popover is not working. Whenever I hover over the text the function is triggered but popover is showing up. I am able to access classes with this.props.classes. It would be great if anyone could help.

import React, { Component } from "react";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import { withStyles } from "@material-ui/core/styles";

const useStyles = (theme) => ({
  root: {
    backgroundColor: "red",
    height: "30px",
  },
  lable: {
    transform: "translate(5px, 2px) scale(1)",
    pointerEvents: "none",
    width: "100%",
    height: "100%",
    padding: "10px",
    color: "red",
  },
  popover: {
    pointerEvents: "none",
    color:"pink"
  },
  paper: {
    padding: theme.spacing(1),
  },
  etc:{
    color: "red"
  }
});

class SomeThing extends Component {
  open;
constructor(props){
  super(props)
  this.handlePopoverClose = this.handlePopoverClose.bind(this);
    this.handlePopoverOpen = this.handlePopoverOpen.bind(this);
  this.state={
    anchorEl: null,
  }
}
componentDidMount(){
  this.open = Boolean(this.state.anchorEl);
}
  handlePopoverOpen = (event) => {
    console.log("triggered!!!", event.currentTarget.innerText);
    this.setState({ anchorEl: event.currentTarget.innerText });
  };

  handlePopoverClose = () => {
    console.log("triggered again!!!", this.props);
    this.setState({ anchorEl: null });
  };
  render() {
    return (
      <div>
        <Typography
          aria-owns={this.open ? "mouse-over-popover" : undefined}
          aria-haspopup="true"
          className={this.props.classes.etc}
          onMouseEnter={this.handlePopoverOpen}
          onMouseLeave={this.handlePopoverClose}
        >
          Hover with a Popover.
        </Typography>
        <Popover
          id="mouse-over-popover"
          className={this.props.classes.popover}
          classes={{
            paper: this.props.classes.paper
          }}
          open={this.open}
          anchorEl={this.state.anchorEl}
          anchorOrigin={{
            vertical: "bottom",
            horizontal: "left"
          }}
          transformOrigin={{
            vertical: "top",
            horizontal: "left"
          }}
          onClose={this.handlePopoverClose}
          disableRestoreFocus
        >
          <Typography>I use Popover.</Typography>
        </Popover>
      </div>
    );
  }
}

export default withStyles(useStyles)(SomeThing);

Solution

  • You can define your open inside your render method; this way, open will always be a boolean and will not be set to undefined — which is the reason why it's not working.

    render() {
      const open = Boolean(this.state.anchorEl);
    
      return (
        <div>
          <Typography
            aria-owns={open ? "mouse-over-popover" : undefined}
            aria-haspopup="true"
            className={this.props.classes.etc}
            onMouseEnter={this.handlePopoverOpen}
            onMouseLeave={this.handlePopoverClose}
          >
            Hover with a Popover.
          </Typography>
          ...
        </div>
      );
    }
    

    Edit smoosh-frost-bvu1y