Next.js 仅在桌面上呈现视频:useEffect 无法对未安装的组件执行 React 状态更新

Next.js render video only on desktop: useEffect can't perform a React state update on an unmounted component

我知道这里已经有多个类似的问题,但我看不出我需要进行哪个异步修复才能完成这项工作。

我有一个 Next.js 网站,我想在其中呈现视频,但仅当我们在桌面上时。我根本不希望视频出现在移动设备上以防止用户首先下载它,为了做到这一点,我编写了自己的 React 挂钩来跟踪 window 大小。

我可以在我的代码中使用 isDesktop 并且一切正常,并且由于我仍处于开发阶段,所以我添加了 window 调整大小侦听器,这样我就可以通过调整我的大小轻松地进行测试window 而不是每次都重新加载页面。

一切都按预期进行,除了这条可怕的消息:

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

这让我抓狂。我有这个代码:

import { useState, useEffect } from 'react';

export function useWindowSize() {
    const isBrowser = typeof window !== 'undefined';
    const [isDesktop, setIsDesktop] = useState<boolean>(false);

    function update() {
        setIsDesktop(window.innerWidth >= 768);
    }

    useEffect(() => {
        if (isBrowser) {
            update();
            window.addEventListener('resize', update, false);
            return () => {
                window.removeEventListener('resize', update, false);
            };
        }
    }, [isBrowser]);

    return { isDesktop };
}

一旦我注释掉 useEffect 中的 update 调用,消息就会消失。但是后来我不再获得初始状态(意思是,在我开始调整 window 大小之前,它不会在我的桌面页面上呈现视频,而这不是应该发生的事情)。

问题在于您是有条件地调用 useEffect 清除函数,它应该始终是静态的。尝试将 isBrowser 条件放入清理函数

useEffect(() => {
  if (isBrowser) {
    update();
    window.addEventListener('resize', update, false);
  }

  return () => {
    isBrowser && window.removeEventListener('resize', update, false);
  };
}, [isBrowser]);