【问题标题】:Close Popover on click in child component单击子组件时关闭弹出框
【发布时间】:2021-11-20 22:22:30
【问题描述】:

我有一个组件,我在其中渲染一个 Popover 组件:

// HeaderMenu.tsx

const HeaderMenu = () => {
  const ShowMenu = () => {
    return (
      <div className={classes.profile}>
        <ul>
          <Notifications />
        </ul>
        <ul>
          <li onClick={handleClose}><Link to={`/profile/${currentUserVar().id}`}>Profile</Link></li>
          <li onClick={handleClose}><Link to='/' onClick={logout}>Logout</Link></li>
        </ul>
      </div>
    );
  };

  return (
    <div>
      <Button onClick={handleClick}>
        <AccountCircleIcon className={classes.profileIcon} />
      </Button>
      <Popover
        id={id}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: 'bottom',
          horizontal: 'left',
        }}
      >
        <ShowMenu />
      </Popover>
    </div>
  );
};

我可以在ShowMenu 函数中使用onClick={handleClose},但我也有一个嵌套组件:Notifications。在这个组件中,我渲染了一个带有一些链接的列表:

// Notifications.tsx

<Link to={`/profile/${notification.followedUser.id}`}>{notification.followedUser.user_name}</Link>{' '}

如果Notifications 组件中的链接已被点击,我将如何调用HeaderMenu 组件中的handleClose 函数来关闭Popover

我可以使用 Reactive 变量触发 Notifications 组件的更改(如果已单击链接)并通过调用 handleClose 函数对 HeaderMenu 组件中的更改做出反应。但我希望有更好的方法。有什么建议吗?

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    在你的 Notifications 组件中添加一个 onRequestClose 属性:

    function Notifications({ onRequestClose }) {
      return <div onClick={onRequestClose}>Notifications</div>;
    }
    
    const ShowMenu = ({ onRequestClose }) => {
      const classes = makeStyles();
    
      return (
        <div className={classes.profile}>
          <ul>
            <Notifications onRequestClose={onRequestClose} />
          </ul>
          <ul>
            <li onClick={onRequestClose}>
              <Link to={`/profile/1`}>Profile</Link>
            </li>
            <li onClick={onRequestClose}>
              <Link to="/" onClick={() => {}}>
                Logout
              </Link>
            </li>
          </ul>
        </div>
      );
    };
    

    在父组件中,像这样向下传递回调:

    const classes = makeStyles();
    const [anchorEl, setAnchorEl] = React.useState(null);
    const open = Boolean(anchorEl);
    const id = open ? "simple-popover" : undefined;
    
    const handleClick = (event) => {
      setAnchorEl(event.currentTarget);
    };
    
    const handleClose = () => {
      setAnchorEl(null);
    };
    
    return (
      <div>
        <Button onClick={handleClick}>
          <AccountCircleIcon className={classes.profileIcon} />
        </Button>
        <Popover
          id={id}
          open={open}
          anchorEl={anchorEl}
          onClose={handleClose}
          anchorOrigin={{
            vertical: "bottom",
            horizontal: "left"
          }}
        >
          <ShowMenu onRequestClose={handleClose} />
        </Popover>
      </div>
    );
    

    现场演示

    【讨论】:

    • 太棒了!没什么特别的,只是将函数回调作为道具传递。我想太多了。
    • 需要注意的一点,在 TS 中 prop 会抱怨 prop types,检查 > stackoverflow.com/questions/57510552/…
    猜你喜欢
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    相关资源
    最近更新 更多