网站搜索

javascript - 如果我刷新页面,matchMedia 不工作


我在 React 中使用 matchMedia 来在页面调整大小时折叠侧边栏。但问题是如果我刷新页面,侧边栏是打开的,而不是关闭的。所以如果我想折叠侧边栏,我需要再次调整页面大小或使用关闭按钮。

const layout = document.getElementById('home-layout');
const query = window.matchMedia('(max-width: 765px)');

  query.onchange = (evt) => {
      if( query.matches ) { 
        changeMenuMinified(true);
        layout.classList.add('extended-layout');
       } 
      else { 
        changeMenuMinified(false);
        layout.classList.remove('extended-layout');
      } 
    };
    query.onchange();
  };
  
  useEffect(() => {
    window.addEventListener('resize', handleResize);
  });

如果我移除 addEventListener,它就能正常工作,我可以重新加载页面并且侧边栏保持关闭,但如果我尝试用按钮打开侧边栏,侧边栏会很快关闭

const handleResize = () => {

    const layout = document.getElementById('home-layout');
    const query = window.matchMedia('(max-width: 765px)');
    query.onchange = (evt) => {
      if( query.matches ) { 
        changeMenuMinified(true);
        layout.classList.add('extended-layout');
       } 
      else { 
        changeMenuMinified(false);
        layout.classList.remove('extended-layout');
      } 
    };
    query.onchange();
  };
  
  useEffect(() => {
    handleResize()
  });

  

侧边栏

答案#1

这里需要考虑的一些事情:

  • 使用当前匹配值初始化你的状态
  • 在 effect 清理函数中移除监听器
  • 别忘了 useEffect 的依赖数组,以避免你的代码在每次渲染时都执行。

你可以在这里找到一个可运行的示例 -> https://codesandbox.io/s/stack-72619755-lpwh6m?file=/src/index.js:0-613

const query = window.matchMedia('(max-width: 765px)')

const App = () => {
  const [minified, changeMenuMinified] = useState(query.matches)

  useEffect(() => {
    const resizeHandler = () => {
      if (query.matches) {
        changeMenuMinified(true)
      } else {
        changeMenuMinified(false)
      }
    }

    query.addEventListener("change", resizeHandler);

    return () => query.removeEventListener("change", resizeHandler);
  })

  return <p>{minified ? 'minified' : 'expanded'}</p>
}

答案#2

那是因为你需要两者才能工作,在加载时和驻留时都是如此,为此你可以这样做:

注意我添加了那个空的依赖数组。

useEffect(() => {
    handleResize();
    window.addEventListener('resize', handleResize);
  },[]);