首页 > 解决方案 > 在 useEffect 挂钩中使用 matchMedia 会导致无限渲染

问题描述

window.matchMedia用来检测屏幕尺寸。我想在页面进入小屏幕时重新加载页面。但是,我的代码导致无限渲染。我怎样才能解决这个问题?

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; 
}

标签: javascriptreactjsreact-hooksmatchmedia

解决方案


本文将引导您完成处理媒体查询更改的过程以及所有部分如何组合在一起,此外,作者还给出了一些如何避免性能损失的提示(React Tips)并提出了解决方案。


推荐阅读