Search code examples
reactjsipadsafari

Why does this code break my site on iPad?


This is the code in question:

const [isOpen, setOpen] = useState(false);

useEffect(() => {
window
  .matchMedia("(min-width: 768px)")
  .addEventListener("change", () => setOpen(false));
}, []);

After going through my code bit by bit, I found that this code block in particular was breaking my site on iPad completely. The site wouldn't load and would instead display a white screen. For context, the code is supposed to close a nav menu when the screen reaches the specified width. It's probably worth noting that this is on an iPad Air 1 from 2013, which I believe is no longer being supported. The site works fine on other iOS devices, just not this one. Is it just a case of outdated software?


Solution

  • It's that because your code is throwing an error at addEventListener. Possibly because of two reasons.

    1. You're trying to grab the event before DOM render. For this you can wrap your 'window' code inside DOMContentLoaded.

      Solution:

      window.addEventListener('DOMContentLoaded', (event) => {
          window
          .matchMedia("(min-width: 768px)")
          .addEventListener("change", () => setOpen(false));
       }

    2. addEventListener isn't compatible with the safari version on your iPad. For this, you can go ahead writing a try{} catch() block and use addListener method.

      Solution:

      try {
         window
           .matchMedia("(min-width: 768px)")
           .addEventListener("change", () => setOpen(false));
      } catch (err) {
         try {
         window
           .matchMedia("(min-width: 768px)")
           .addListener("change", () => setOpen(false));
         } catch (err1) {
           console.error(err1);
         }
      }

    For more references on matchMedia and addEventListener look here at MDN Docs