如何在 Next.js 中访问客户端 window 方法

How to access client-side window method in Next.js

我正在尝试使用 Next.js 中的 DOM 媒体查询来更改我的应用程序的结构。正常的媒体查询(CSS)没有问题。在“纯”React 中,我可以做这样的事情:

function HomePage () {
  const [landscape, setLandscape] =  useState(false)

  useEffect(() => {

    const landscapeHandler = e => {
      console.log ("Change in landscape")
      setLandscape({matches: e.matches});
    }
   
    window.matchMedia("((orientation:landscape)").addEventListener('change', landscapeHandler);

    return () => {
      window.removeEventListener('change', landscapeHandler);
    }


}, [])
}

但是,使用 Next 时,更改屏幕方向根本没有任何作用。有解决方法吗?我一直认为 useEffect 只是客户端,因此是进行此类媒体查询的正确位置...... 非常感谢!

Next.js先在服务端执行代码,再在客户端执行。因此,当它在服务器中执行时,window 将是未定义的。

你可以像下面的代码那样做,

 useEffect(() => {
   
    if (typeof window !== "undefined") {
     window.matchMedia("((orientation:landscape)").addEventListener('change', landscapeHandler);
    }
    // component Will Unmount
    return () => {
      if (typeof window !== "undefined") {
        window.removeEventListener('change', landscapeHandler);
      }
    };
  }, []);

您可以使用 'orientationchanged' 侦听器,但我认为它已经过时了。

您可以尝试使用 'resize' 侦听器。

 useEffect(() => {

    const handleChange = () => {
      

      const width = document.documentElement.clientWidth
      const height = document.documentElement.clientHeight
      
      const orientation = width > height ? 'landscape' : 'portrait';

      console.log('orientation: ', orientation, 'width', width, 'height', height)

    }
    if (typeof window !== 'undefined') {
        const unsub = window.addEventListener('resize', handleChange)
        return () => unsub();
    }

  },[])