Lin Kassem
Lin Kassem

Reputation: 55

In "@headlessui/react", how to pass 'Popover' 'open' prop to it's parent component

I am using the "Popover" component from "@headlessui/react" & I want to take action when the popover open/close without changing the default open/close behavior.

So I was thinking of passing the 'open' prop of the "Popover" component to a wrapper component & then execute the fn that I want to execute inside a useEffect. However I am not sure how I can do this.

https://headlessui.dev/react/popover

Upvotes: 1

Views: 3801

Answers (1)

J.D. Sandifer
J.D. Sandifer

Reputation: 906

It sounds like you're on the right track with the wrapper component. However, I'd suggest passing the function you'd like to execute down to the popover and running it in a useEffect there.

Here's the idea (based on one of the examples from the Headless UI site):

import { useEffect } from 'react'
import { Popover } from '@headlessui/react'
import { ChevronRightIcon } from '@heroicons/react/solid'

function PopoverContent({ open, func }) {
  useEffect(() => {
    if (open) {
      func()
    }
  }, [ open ])

  return (
    <>
       <Popover.Button>
         <span>Solutions</span>
         <ChevronRightIcon
           className={`${open ? 'transform rotate-90' : ''}`}
         />
       </Popover.Button>

       <Popover.Panel>{/* ... */}</Popover.Panel>
    </>
  )
}
  

function MyPopover() {
  const functionToExecuteOnOpen = () => {
     // do something
  }

  return (
    <Popover>
      {({ open }) => (
        <PopoverContent
          open={open}
          func={functionToExecuteOnOpen}
        />
      )}
    </Popover>
  )
}

You can remove the if statement in the useEffect and simply call the function if you want it to run every time open changes (regardless of the value).

Upvotes: 2

Related Questions