reactjs 在react中替换id的最佳方法是什么?

ldioqlga  于 2022-12-22  发布在  React
关注(0)|答案(1)|浏览(138)

我正在开发一个菜单组件,在id的帮助下,我使它可以在组件外单击时打开和关闭。
但是我知道我做错了什么,如果我打开其他菜单,那么前一个菜单就不会关闭,我试图传递props来覆盖id,但是它们不稳定(事实上,它们完全停止工作了,但是我没有进一步深入寻找答案)
我明白这不是最佳实践。组件必须能够被重用。所以我想如何改进它,我应该使用refs?Hook onChange?你认为哪种方法更方便,更实用?

import { useState } from "react";

function OverflowMenu(props) {
  const [isActive, setIsActive] = useState(false);
  const handleClick = (event) => {
    setIsActive((current) => !current);
    document.addEventListener("click", (event) => {
      const target = event.target;
      if (!target.closest(`#wrapper`) && !target.closest(`#menu`)) {
        setIsActive(false);
      }
    });
  };

  return (
    <>
      <div
        id={"wrapper"}
        onClick={handleClick}
        className="relative flex cursor-pointer"
      >
        {props.children} {props.content}
        <div
          id={"menu"}
          className={`${!isActive && "hidden"} 
          
          ${props.topRight && "-right-0 bottom-full"}
          ${props.topLeft && "-left-0 bottom-full"}
          ${props.bottomRight && "-right-0 top-full"}
          ${props.bottomLeft && "-left-0 top-full"}    
          
          absolute z-20 my-[4px] flex min-w-[112px] max-w-[280px] flex-col`}
        >
          <div className="scroll flex max-h-[310px] min-w-max flex-col overflow-hidden overflow-y-auto rounded-[8px] bg-blue-50 py-[8px] shadow-mm-1 dark:bg-gray-800 ">
            <>{props.menu}</>
          </div>
        </div>
      </div>
    </>
  );
}

export { OverflowMenu };
zaqlnxep

zaqlnxep1#

你好@sllmn,

有几种方法可以改进当前的实现。
一种选择是使用ref钩子,你可以用它来传递HTML元素的引用。

const menuRef = useRef(null)

const handleClick = (event) => {
  setIsActive((current) => !current)
  if (!menuRef.current.contains(event.target)) {
    setIsActive(false)
  }
}
// code....
<div
  id={'menu'}
  ref={menuRef}
  className={""}>
  // code....
</div>

另一个选择。我在网上找到的,这是一个很好的选择。使用useOnClickOutside挂钩。你需要先安装它。
yarn add react-use
现在,您可以通过导入该库来使用。
import { useOnClickOutside } from 'react-use';

import { useState, useRef } from 'react';
import { useOnClickOutside } from 'react-use';

function OverflowMenu(props) {
  const [isActive, setIsActive] = useState(false);
  const menuRef = useRef(null);

  useOnClickOutside(menuRef, () => setIsActive(false));

  const handleClick = (event) => {
    setIsActive((current) => !current);
  };

  return (
    <>
      <div
        id={"wrapper"}
        onClick={handleClick}
        className="relative flex cursor-pointer"
      >
        {props.children} {props.content}
        <div
          id={"menu"}
          ref={menuRef}
          className={`${!isActive && "hidden"} 
          
          ${props.topRight && "-right-0 bottom-full"}
          ${props.topLeft && "-left-0 bottom-full"}
          ${props.bottomRight && "-right-0 top-full"}
          ${props.bottomLeft && "-left-0 top-full"}    
          
          absolute z-20 my-[4px] flex min-w-[112px] max-w-[280px] flex-col`}
        >
          <div className="scroll flex max-h-[310px] min-w-max flex-col overflow-hidden overflow-y-auto rounded-[8px] bg-blue-50 py-[8px] shadow-mm-1 dark:bg-gray-800 ">
            <>{props.menu}</>
          </div>
        </div>
      </div>
    </>
  );
}
export { OverflowMenu };

相关问题