You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js使用masonry-layout报错:ReferenceError: window is not defined

解决Next.js中masonry-layout/packery的「window is not defined」错误

问题根源是Next.js的服务端渲染(SSR)机制:服务端环境没有window对象,而masonry、packery这类库依赖浏览器环境,直接导入会在服务端执行阶段触发错误,导致部署失败。以下是几种可靠的解决方法:

方法1:使用Next.js动态导入(推荐)

通过next/dynamic动态导入包含masonry的组件,并禁用SSR,确保组件只在客户端加载:

// 页面文件中
import dynamic from 'next/dynamic';

// 动态导入你的瀑布流组件,禁用SSR
const MasonryGrid = dynamic(() => import('../components/MasonryGrid'), {
  ssr: false,
  loading: () => <div>加载中...</div> // 可选的加载占位符
});

export default function Home() {
  return (
    <div>
      <MasonryGrid />
    </div>
  );
}

在你的MasonryGrid组件中正常使用masonry即可:

// components/MasonryGrid.jsx
import { useEffect, useRef } from 'react';
import Masonry from 'masonry-layout';

export default function MasonryGrid() {
  const gridRef = useRef(null);

  useEffect(() => {
    const masonryInstance = new Masonry(gridRef.current, {
      itemSelector: '.grid-item',
      columnWidth: 200,
      gutter: 15
    });

    // 组件卸载时销毁实例
    return () => masonryInstance.destroy();
  }, []);

  return (
    <div className="grid" ref={gridRef}>
      <div className="grid-item">内容1</div>
      <div className="grid-item">内容2</div>
      {/* 更多瀑布流项 */}
    </div>
  );
}

方法2:在客户端生命周期中初始化库

利用React的useEffect钩子(仅在客户端执行),在确认window存在后再初始化masonry/packery:

import { useEffect, useRef } from 'react';

export default function PackeryGrid() {
  const containerRef = useRef(null);

  useEffect(() => {
    // 确保仅在客户端环境执行
    if (typeof window === 'undefined' || !containerRef.current) return;

    // 动态导入packery(避免服务端加载)
    import('packery')
      .then(({ default: Packery }) => {
        const packeryInstance = new Packery(containerRef.current, {
          itemSelector: '.packery-item',
          gutter: 10
        });

        return () => packeryInstance.destroy();
      });
  }, []);

  return (
    <div className="packery-container" ref={containerRef}>
      <div className="packery-item">内容A</div>
      <div className="packery-item">内容B</div>
    </div>
  );
}

为什么修改node_modules无效?

你修改node_modules中的代码不会被版本控制系统追踪,部署时Netlify会重新安装依赖包,你的修改会被覆盖。而且直接修改第三方库源码会导致后续依赖更新时丢失更改,是不可持续的解决方案。

内容的提问来源于stack exchange,提问作者Mayowa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:25:07