React-tooltip: Multiple tooltip in same page open all at the same time

Created on 20 Apr 2018  路  8Comments  路  Source: wwayne/react-tooltip

I usually have multiple react-tooltip for each place I want to show a tooltip.

Problem, after clicking the second tooltip, the first tooltip does not close. Therefore, user is seeing both tooltip opening at the same time.

My assumption is that data-for and id is there to avoid this from happening

You can also see this demo on Edit 038px2yrmp

<a data-event="click" data-for="first-click" data-tip="firstClick">
   first tooltip
</a>
<ReactTooltip globalEventOff="click" id="first-click" />

<a data-event="click" data-for="second-click" data-tip="second-click">
  second tooltip
</a>
<ReactTooltip globalEventOff="click" id="second-click" />

I understand that a better way is to put only one reacttooltip for the whole app. But, is there any way to make multiple reacttooltip to work?

Most helpful comment

Not sure if that will fulfill your requirements, but if you reach this issue there is a chance that below workaround may come in handy:

const TooltipDemo = (props) => {
  const [isTooltipOpen, setTooltipOpen] = React.useState(false)
  const tooltipWrapperRef = React.useRef(null)

  const hideTooltipHandler = React.useCallback(() => {
    const tooltipWrapperEl = tooltipWrapperRef.current
    if (tooltipWrapperEl) {
      ReactTooltip.hide(tooltipWrapperEl)
      setTooltipOpen(false)
      document.removeEventListener("click", hideTooltipHandler)
    }
  }, [])

  const onTooltipTriggerClick = React.useCallback(() => {
    const tooltipWrapperEl = tooltipWrapperRef.current
    if (tooltipWrapperEl) {
      if (isTooltipOpen) {
        ReactTooltip.hide(tooltipWrapperEl)
        setTooltipOpen(false)
      } else {
        ReactTooltip.show(tooltipWrapperEl)
        setTooltipOpen(true)

        document.addEventListener("click", hideTooltipHandler)
      }
    }
  }, [isTooltipOpen])

  React.useEffect(() => {
    return () => {
      document.removeEventListener("click", hideTooltipHandler)
    }
  }, [])

  return (
    <section>
      <div
        data-tip
        data-for={props.id}
        ref={tooltipWrapperRef}
        data-event="click"
        data-event-off=""
        onClick={onTooltipTriggerClick}
      >
        /* your tooltip trigger here */
      </div>
      <ReactTooltip
        id={props.id}
        place="bottom"
        type="light"
        border
        isCapture
        effect="solid"
      >
        /* your tooltip content here */
      </ReactTooltip>
    </section>
  )
}

With multiple TooltipDemo components on one page the problem described by @joedevgee no longer occurs.

All 8 comments

Thank you for the working sample code and example code.
This is obviously only a problem when using the data-event="click" activation - so one work-around is to use a hovering tool-tip.
data-id is primarily used to connect a specific tooltip with a target, but I can see how it could help in this case. Do you think you might be able to look for a solution and submit a pull request?

A potential work-around is to add an afterShow event handler and hide the other tooltips manually.

@aronhelser Working on a major release now, will come back and raise a PR. Thanks for the solution

@aronhelser can you explain more about this work-around ? how can you hide other tooltips after the show of some tooltip ?

@joedevgee something new about this PR ?

Not sure if that will fulfill your requirements, but if you reach this issue there is a chance that below workaround may come in handy:

const TooltipDemo = (props) => {
  const [isTooltipOpen, setTooltipOpen] = React.useState(false)
  const tooltipWrapperRef = React.useRef(null)

  const hideTooltipHandler = React.useCallback(() => {
    const tooltipWrapperEl = tooltipWrapperRef.current
    if (tooltipWrapperEl) {
      ReactTooltip.hide(tooltipWrapperEl)
      setTooltipOpen(false)
      document.removeEventListener("click", hideTooltipHandler)
    }
  }, [])

  const onTooltipTriggerClick = React.useCallback(() => {
    const tooltipWrapperEl = tooltipWrapperRef.current
    if (tooltipWrapperEl) {
      if (isTooltipOpen) {
        ReactTooltip.hide(tooltipWrapperEl)
        setTooltipOpen(false)
      } else {
        ReactTooltip.show(tooltipWrapperEl)
        setTooltipOpen(true)

        document.addEventListener("click", hideTooltipHandler)
      }
    }
  }, [isTooltipOpen])

  React.useEffect(() => {
    return () => {
      document.removeEventListener("click", hideTooltipHandler)
    }
  }, [])

  return (
    <section>
      <div
        data-tip
        data-for={props.id}
        ref={tooltipWrapperRef}
        data-event="click"
        data-event-off=""
        onClick={onTooltipTriggerClick}
      >
        /* your tooltip trigger here */
      </div>
      <ReactTooltip
        id={props.id}
        place="bottom"
        type="light"
        border
        isCapture
        effect="solid"
      >
        /* your tooltip content here */
      </ReactTooltip>
    </section>
  )
}

With multiple TooltipDemo components on one page the problem described by @joedevgee no longer occurs.

@kkowalczuk do you mind doing your workaround using render props? I don't understand hooks that much yet

you need to set data-event-off property
data-event-off="mouseleave"

or you can combine with click if you need to work it on hover and click together
data-event-off="mouseleave click"

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kristinadarroch picture kristinadarroch  路  3Comments

jhlee4 picture jhlee4  路  3Comments

benbro picture benbro  路  3Comments

Ganasist picture Ganasist  路  3Comments

lovetann picture lovetann  路  3Comments