javascriptreactjspopper.jsreact-popper

how to get single Popper to render in mapping using React usePopper


I have a mapping in a reactstrap table. The first <td> of every row should open a popper/tooltip like this:

design to reproduce

I added the popper to my code using usePopper hook from react-popper library.

I'm successfully rendering the popper but since the element is inside a mapping I'm currently triggering the state on all the poppers of the table:

current localhost

This is my code:

  const boxRef = useRef()
  const tooltipRef = useRef()

  const [isOpen, setIsOpen] = useState(false)

  const { styles, attributes } = usePopper(boxRef.current, tooltipRef.current)

  const handleClick = () => {
    setIsOpen(!isOpen)
  }
<tbody>
  {playersDetailTable.map((item, index) => {
    return (
      <>
        <tr className={stylesModule.table_row_PlayersManagementTable} key={index}>
          <td style={nicknameStyles} ref={boxRef} onClick={handleClick}>
            {item.nickname}
            {/* NICKNAME POPPER */}
            <div
              {...attributes.popper}
              ref={tooltipRef}
              className={`${stylesModule.Tooltip} ${
                !isOpen ? stylesModule.Tooltip__hidden : null
              }`}
            >
              {item.nickname}
            </div>
            {/* NICKNAME POPPER */}
          </td>
          <td>{item.name}</td>
          <td>{item.lastName}</td>
          <td>{item.portal}</td>
          <td>{item.affiliate}</td>
          <td className='text-center'>
            <img src={item.countryImg} alt='Country flag' height={12} width={16} />Ï
          </td>
        </tr>
</tbody>

How do I show only the correct popper when isOpen state is set to true while keeping the popper element inside the mapping?


Solution

  • I ended up moving the popper outside of the table mapping, and saved the popper data in a new state const [popperData, setPopperData] = useState(null).

    I'm setting the data for the single popper and opening it every time the user clicks on the nickname table cell inside the mapping, achieving the result I wanted

    <td
      style={nicknameStyles}
      ref={boxRef}
      onClick={() => {
        setPopperData(item)
        setIsOpen(!isOpen)
      }}
    >
      {item.nickname}
    </td>