Using matchMedia in a useEffect hook is causing infinite renders

3.2k views Asked by At

I am using window.matchMedia to detect the screen size. I want reload the page when it goes to a small screen. However, my code is causing infinite renders. How can I fix this?

export default function App(props) {
  const small = useMedia("(max-width: 400px)");
  const large = useMedia("(min-width: 800px)");
  if(small) {
    window.location.reload();
  }
  return (
    <div className="Media">
      <h1>Media</h1>
      <p>Small? {small ? 'Yes' : 'No'}.</p>
      <p>Large? {large ? 'Yes' : 'No'}.</p>
    </div>
  );
}

function useMedia(query) {
   const [matches, setMatches] = useState(
     window.matchMedia(query).matches
   );
   useEffect(() => {
    const media = window.matchMedia(query);
    if (media.matches !== matches) {
      setMatches(media.matches);
    }

    const listener = () => setMatches(media.matches);
    media.addListener(listener);

    return () => media.removeListener(listener);
   }, [query]);

   return matches; 
}
1

There are 1 answers

3
Mu-Majid On

This Article walks you through the process of handling Media query changes and how all the pieces fit together, in addition, the author also gives some tips (React tips) of how to avoid performance hits and suggests a solution.