0

I made a popup using useState which worked in React 17 but stopped in React 18 without any errors being displayed.

When I set the isVisible state to be true initially the Popup gets displayed but setting it to using the button does not work.

I'm wondering why this is the case and how I can migrate it to React 18 since I need it for other dependencies in my project.

{isVisible && (
  <Popup
    visible={isVisible}
    toggle={() => {
      setLightboxVisible(false);
      document.body.classList.toggle("body-noscroll-class");
    }}
  >
    Lorem Ipsum dolor sit amet.
  </Popup>
)}

<button 
  onClick={() => {
    setLightboxVisible(true);
  }}>
Show Popup
</button>

Here is a Codesandbox which shows the behavior.

Alexander Hörl
  • 578
  • 4
  • 11
  • 24

2 Answers2

2

You shouldn't use css display to show or hide elements in react. Just use react code to either render it to the DOM or don't render it to the DOM. You were already doing this in app.js, and then in your popup you were doing it again. So in the css you didn't need the display property. See simplified version in the new codesandbox.

Use useEffect to listen for changes to isVisible to determine when to toggle the css class on the body.

Add an onClick to the modal backdrop, but then on the inner div prevent the click event from bubbling up to the parent by using e.stopPropagation.

See these changes in the updated CodeSandbox.

Anthony Tietjen
  • 1,032
  • 2
  • 8
  • 19
  • Really good point you're making here. It's always nice to see it not mixing React and vanilla. Did you consider portal to achieve modal which is detached from the nested html? – Miłosz Jun 03 '22 at 08:29
  • The problem here is that by default the `body-noscroll-class` is activated. – Alexander Hörl Jun 03 '22 at 10:36
0

Fixed by changing click to mousedown in the useOuterClick hook, as suggested by @Miłosz

https://codesandbox.io/s/relaxed-cdn-vjih7v?file=/src/hooks.js

Alexander Hörl
  • 578
  • 4
  • 11
  • 24