尽管将props传播到该组件,但材料 UI 工具提示不会显示在自定义组件上

IT技术 reactjs tooltip material-ui
2021-05-15 11:53:30

当鼠标悬停在组件上时,我很难让 Material UI 工具提示真正出现。据我所知,我正在做工具提示组件的最简单的实现:我直接导入它(没有自定义样式或其他任何东西),我将它包裹在另一个组件周围,在顶层展开它的props。

从阅读文档来看,它应该是那么简单,但它并没有出现在悬停时,并且在 React DevTools 中,我看到 anchorEl 属性是未定义的。

import Tooltip from '@material-ui/core/Tooltip';

const containerComponent = () => (
    <Tooltip text="Planner"><PlannerIcon /></Tooltip>
)

PlannerIcon.js

const PlannerIcon = (props) => (
  <Icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"
    {...props}
  >
    <path d="M14.71,3.11V14.88H2.94V3.11H14.71m1-1H1.94V15.88H15.71V2.11Z"/>
    <line x1="1.94" y1="9" x2="15.71" y2="9" strokeMiterlimit="10"/>
    <line x1="8.83" y1="2.12" x2="8.83" y2="15.77" strokeMiterlimit="10"/>
  </Icon>
  );
4个回答

您的 Tooltip 无法正常工作,因为 Material-UI Tooltip 的子级必须能够保存 ref。

以下内容可以包含 ref:

  • 任何 Material-UI 组件
  • 类组件,即 React.Component 或 React.PureComponent
  • DOM(或主机)组件,例如 div 或按钮
  • React.forwardRef 组件
  • React.lazy 组件
  • React.memo 组件

PlannerIcon 不是上述任何一个,它是一个功能组件我会为这个问题提出两种解决方案:

  1. 以 div 作为父元素的Surround PlannerIcon(div 可以保存一个 ref):

    <Tooltip text="Planner">
      <div>
       <PlannerIcon />
      </div>
    </Tooltip>
    
  2. PlannerIcon转换为类组件:

    class PlannerIcon extends React.Component {
      render(){
        return(
         <Icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"
          {...props}
         >
           <path d="M14.71,3.11V14.88H2.94V3.11H14.71m1-1H1.94V15.88H15.71V2.11Z"/>
           <line x1="1.94" y1="9" x2="15.71" y2="9" strokeMiterlimit="10"/>
           <line x1="8.83" y1="2.12" x2="8.83" y2="15.77" strokeMiterlimit="10"/>
         </Icon>
        )
      }
    };
    

不需要 div 解决方法或将您的功能组件变成一个类。您可以改用 forwardRef,它也可以工作:

const PlannerIcon = React.forwardRef((props, ref) => (
  <Icon xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"
    {...props}
    ref={ref}
  >
    <path d="M14.71,3.11V14.88H2.94V3.11H14.71m1-1H1.94V15.88H15.71V2.11Z"/>
    <line x1="1.94" y1="9" x2="15.71" y2="9" strokeMiterlimit="10"/>
    <line x1="8.83" y1="2.12" x2="8.83" y2="15.77" strokeMiterlimit="10"/>
  </Icon>
  ));

我不确定这个Icon组件是关于什么的,你可能需要把它变成一个<svg>标签。

如果有人使用typescript,语法有点混乱,第一种类型是用于的ref,第二种是用于props(不要问我为什么):

const PlannerIcon = React.forwardRef<SVGSVGElement | null, IPlannerIconProps>((props, ref) => {
    ...
});

我相信您需要 title="Planner" 而不是 text="Planner"。

<Tooltip title="Planner"><PlannerIcon /></Tooltip>

我知道这可能很奇怪,但也许尝试将 svg 图标作为组件导入,因为 react 16.4(现在不确定)您可以将 svgs 作为组件导入。

import { ReactComponent as YourName} from './assets/yourfile.svg';

那么你可以简单地这样做:

const PlannerIcon = (props) => (
  <YourName {...props}/>
  );

如果您尝试过并且有帮助,请告诉我。

@edit 我在他们的文档中没有看到任何称为 text 的props,也许你是说标题? 工具提示api