Conditional rendered elements fire as outside click events
Closed this issue · 6 comments
Came across an issue when conditionally rendering elements within a portal. Buttons render and work properly if used individually but when conditionally rendered the onClick events close the portal since 'outside' click events. Setting the closeOnOutsideClick: false
works fine as a temporary fix but was curious if there was a known solution. Also tried binding e.stopPropagation()
in onClick events.
AddTaskCard.js
{isOpen && (
<>
<Portal>
<div className="pointer-events-none fixed w-full h-full top-0 left-0 flex items-center justify-center">
<div className="modal-overlay absolute w-full h-full bg-gray-800 opacity-50"></div>
</div>
</Portal>
<Portal>
<AddTaskModal close={closePortal} items={dropItems} />
</Portal>
</>
)}
AddTaskModal.js
const [viewAll, setViewAll] = useState(false);
const viewAllItems = () => {
setViewSize(items.length);
setViewAll(!viewAll);
};
const resetView = () => {
setViewSize(3);
setViewAll(!viewAll);
};
...
<div className="flex justify-end p-3 items-center">
{/* does not work */}
{viewAll ? (
<ResetViewButton onClick={resetView} />
) : (
<ViewAllButton onClick={viewAllItems} />
)}
{/* works */}
<ResetViewButton onClick={resetView} />
{/* also works */}
<ViewAllButton onClick={viewAllItems} />
</div>
Could you make a codesandbox with a repro of this bug please :)
Thanks for looking into this
https://codesandbox.io/embed/charming-burnell-ld2gf
Finally got time to look at this today. There seems to be some sort of race condition. What I think is happening is react's state is updating the dom before the document.addEventListener('click', handleOutsideClick)
fires. Because of this, the element is removed from the dom before we check if portal.current.contains(clickedElement)
. Since the clickedElement is no longer in the dom, it shows it is not a child of the portal. Hm...
I think I figured it out. Instead of document.addEventListener('click', handleOutsideClick)
we need document.addEventListener('mousedown', handleOutsideClick)
. Check it https://codesandbox.io/s/stupefied-kalam-wwkl3
Update your sandbox to v1.0.2
of react-useportal
it should work
Closing, feel free to reopen if it didn't fix the problem