使用 Material-UI 的数组中的多个悬停弹出框仅打开一个弹出框

Zan*_*hin 3 reactjs material-ui react-redux

我试图在一个页面上使用多个弹出窗口,但唯一要打开的弹出窗口是数组中的最后一个,无论您悬停在哪个触发元素上。这是使用 Material-UI v1.0.0-beta.46。

class MultiplePopover extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      open: false,
      anchorEl: null,
    };
    this.handlePopoverOpen = this.handlePopoverOpen.bind(this);
    this.handlePopoverClose = this.handlePopoverClose.bind(this);
  }
  handlePopoverOpen(event) {
    this.setState({
      anchorEl: event.target,
    });
  }
  handlePopoverClose() {
    this.setState({
      anchorEl: null,
    });
  }

  render() {
    const { classes } = this.props;
    const { anchorEl } = this.state;
    const open = !!anchorEl;


    const multi = [
      {
        _id: 0,
        name: 'name1',
        hoverText: 'text1',
        linkUrl: '#',
      },
      {
        _id: 1,
        name: 'name2',
        hoverText: 'text2',
        linkUrl: '#',
      },
      {
        _id: 2,
        name: 'name3',
        hoverText: 'text3',
        linkUrl: '#',
      },
    ]

    return (
      <div className="wrapper">
        <ul>
          {multi.map(m => (
            <li
              key={m._id}
            >
              <Typography
                onMouseEnter={this.handlePopoverOpen}
                onMouseLeave={this.handlePopoverClose}
              >
                {m.name} 
              </Typography>
              <Popover
                className={classes.popover}
                classes={{
                  paper: classes.paper,
                }}
                open={open}
                anchorEl={anchorEl}
                anchorOrigin={{
                  vertical: 'bottom',
                  horizontal: 'center',
                }}
                transformOrigin={{
                  vertical: 'bottom',
                  horizontal: 'center',
                }}
              >
                <Typography>
                  <a
                    href="{m.linkUrl}"
                    target=" /blank"
                  >
                    {m.hoverText}
                  </a>
                </Typography>
              </Popover>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

我试图按照这篇文章中的答案进行操作,如果一页上有很多,则 Popover 不起作用。如何管理它们?但我无法让它工作。

知道如何让每个弹出框分别打开吗?

你可以在这里看到一个活生生的例子:https : //codesandbox.io/s/1r1zjmj163

asi*_*niy 10

你这样做有点不对。

第一的。open声明状态中仅存在某些元素,但未声明打开了哪个元素。我带来了新openedPopoverId的状态(默认为空)。所以,在这种情况下,你必须检查你的Popover组件

open={this.state.openedPopoverId === m._id}
Run Code Online (Sandbox Code Playgroud)

第二。您必须在 mouseEnter 事件上传递此值,以便:

<Typography
  onMouseEnter={this.handlePopoverOpen}
Run Code Online (Sandbox Code Playgroud)

变成

onMouseEnter={(e) => this.handlePopoverOpen(e, m._id)}
Run Code Online (Sandbox Code Playgroud)

第三。还要更改事件处理程序:

  handlePopoverOpen(event, popoverId) {
    this.setState({
      openedPopoverId: popoverId,
      anchorEl: event.target,
    });
  }
  handlePopoverClose() {
    this.setState({
      openedPopoverId: null,
      anchorEl: null,
    });
  }
Run Code Online (Sandbox Code Playgroud)

最终代码(经过测试,有效):

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Typography from 'material-ui/Typography';
import Popover from 'material-ui/Popover';

const styles = ({
  paper: {
    padding: '20px',
    width: '14vw',
  },
  popover: {
    pointerEvents: 'none',
  },
});

class MultiplePopover extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      open: false,
      anchorEl: null,
    };
    this.handlePopoverOpen = this.handlePopoverOpen.bind(this);
    this.handlePopoverClose = this.handlePopoverClose.bind(this);
  }
  handlePopoverOpen(event, popoverId) {
    this.setState({
      openedPopoverId: popoverId,
      anchorEl: event.target,
    });
  }
  handlePopoverClose() {
    this.setState({
      openedPopoverId: null,
      anchorEl: null,
    });
  }

  render() {
    const { classes } = this.props;
    const { anchorEl, openedPopoverId } = this.state;

    const multi = [
      {
        _id: 0,
        name: 'name1',
        hoverText: 'text1',
        linkUrl: '#',
      },
      {
        _id: 1,
        name: 'name2',
        hoverText: 'text2',
        linkUrl: '#',
      },
      {
        _id: 2,
        name: 'name3',
        hoverText: 'text3',
        linkUrl: '#',
      },
    ]

  console.log(openedPopoverId)

    return (
      <div className="wrapper">
        <ul>
          {multi.map(m => (
            <li
              key={m._id}
            >
              <Typography
                onMouseEnter={(e) => this.handlePopoverOpen(e, m._id)}
                onMouseLeave={this.handlePopoverClose}
              >
                {m.name} 
              </Typography>
              <Popover
                className={classes.popover}
                classes={{
                  paper: classes.paper,
                }}
                open={openedPopoverId === m._id}
                anchorEl={anchorEl}
                anchorOrigin={{
                  vertical: 'bottom',
                  horizontal: 'center',
                }}
                transformOrigin={{
                  vertical: 'bottom',
                  horizontal: 'center',
                }}
              >
                <Typography>
                  <a
                    href="{m.linkUrl}"
                    target=" /blank"
                  >
                    {m.hoverText}
                  </a>
                </Typography>
              </Popover>
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

MultiplePopover.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(MultiplePopover);
Run Code Online (Sandbox Code Playgroud)