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

Next.js中Masonry布局初始化失败:动态导入与useEffect尝试无效

Next.js中Masonry布局初始化失败的解决方案

你的两种尝试存在的问题:

  • 第一种方案错误点:

    1. 不能在useEffect钩子内使用dynamic导入masonry-layout,dynamic是用于组件级别的异步加载,返回的是Promise,直接new Masonry会因为模块未加载完成而报错。
    2. 外部声明的msnry是空字符串,内部又用var msnry重新声明,形成变量遮蔽,导致useEffect的依赖无效,初始化逻辑执行异常。
  • 第二种方案错误点:
    直接在组件顶部导入masonry-layout会触发Next.js的SSR渲染错误,因为Masonry依赖浏览器的window对象,服务端渲染时没有这个环境,导致模块加载失败。


正确实现方式

使用动态导入禁用SSR,配合React ref获取DOM元素(比querySelector更可靠,避免全局选择器冲突),同时在组件卸载时清理Masonry实例防止内存泄漏:

"use client";
import React, { useEffect, useRef } from "react";
import dynamic from "next/dynamic";

// 动态导入Masonry并禁用SSR
const Masonry = dynamic(() => import("masonry-layout"), { ssr: false });

export default function MasonryUI() {
  const gridRef = useRef(null);
  let masonryInstance = null;

  useEffect(() => {
    // 确保在客户端环境且DOM元素已挂载
    if (gridRef.current && typeof window !== "undefined") {
      // 初始化Masonry
      masonryInstance = new Masonry(gridRef.current, {
        itemSelector: ".grid-item",
        columnWidth: 200,
      });
    }

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

  return (
    <>
      <h1>Masonry - columnWidth</h1>
      {/* 使用ref绑定grid容器 */}
      <div className="grid" ref={gridRef}>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--width2 grid-item--height2"></div>
        <div className="grid-item grid-item--height3"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item grid-item--width3"></div>
        <div className="grid-item"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item grid-item--width2 grid-item--height3"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--width2 grid-item--height2"></div>
        <div className="grid-item grid-item--width2"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height3"></div>
        <div className="grid-item grid-item--height2"></div>
        <div className="grid-item"></div>
        <div className="grid-item"></div>
        <div className="grid-item grid-item--height2"></div>
      </div>
    </>
  );
}

额外注意事项

  1. 确保已安装masonry-layout依赖:npm install masonry-layout
  2. 添加基础样式保证布局生效(比如给grid和grid-item设置宽高、间距):
.grid {
  margin: 0 auto;
}
.grid-item {
  width: 200px;
  height: 150px;
  margin-bottom: 10px;
  background: #ccc;
}
.grid-item--width2 { width: 410px; }
.grid-item--width3 { width: 620px; }
.grid-item--height2 { height: 310px; }
.grid-item--height3 { height: 460px; }

内容的提问来源于stack exchange,提问作者The Old County

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:27:34