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

React-Grid-Layout递归子网格自定义宽度计算失效的解决问询

递归React Grid Layout子网格宽度不生效问题

我实现了一个递归渲染自身的CustomLayout组件,基于react-grid-layout构建,根元素显示在主网格,包含children的元素会递归创建子网格。主网格宽度设为1200px,希望子网格宽度按公式width={item.w * 67}计算,但直接传递该值无效,子网格仍继承父级宽度。

现有组件代码

import "./styles.css";
import GridLayout from "react-grid-layout";
import React from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

export default function CustomLayout({ layout, onDragStart, onDragStop }) {
  const [isDraggable, setIsDraggable] = React.useState(true);

  return (
    <GridLayout
      className="layout"
      onDragStart={onDragStart}
      onDragStop={onDragStop}
      layout={layout}
      cols={12}
      rowHeight={80}
      width={1200}
      isDraggable={isDraggable}
    >
      {layout.map((item) => {
        if (item.children) {
          return (
            <div
              onClick={(e) => console.log(e.currentTarget.textContent[0])}
              key={item.i}
              style={{ background: "pink", border: "1px solid black" }}
            >
              <CustomLayout
                layout={item.children}
                width={item.w * 10}
                onDragStart={() => {
                  setIsDraggable(false);
                }}
                onDragStop={() => {
                  setIsDraggable(true);
                }}
              />
            </div>
          );
        } else {
          return (
            <div
              key={item.i}
              style={{ background: "purple" }}
              // onClick={(e) => console.log(item.i)}
            >
              {item.i}
            </div>
          );
        }
      })}
    </GridLayout>
  );
}

Layout数据结构

const layout = [
  { i: "b", x: 0, y: 0, w: 3, h: 2, isResizable: true },
  { i: "c", x: 4, y: 0, w: 1, h: 2, isResizable: true },
  {
    i: "k",
    x: 0,
    y: 0,
    w: 6,
    h: 5,
    isResizable: true,
    children: [
      { i: "e", x: 0, y: 0, w: 2, h: 2, isResizable: true },
      {
        i: "d",
        x: 2,
        y: 4,
        w: 3,
        h: 4,
        isResizable: true,
        children: [
          { i: "e", x: 0, y: 0, w: 1, h: 1, isResizable: true },
          { i: "d", x: 1, y: 0, w: 1, h: 2, isResizable: true }
        ]
      }
    ]
  }
];

解决方案

问题核心两点:

  1. 组件未接收并使用传入的width props,硬编码固定值1200
  2. 子网格的容器div未限制宽度,导致子GridLayout无法应用自定义宽度

修改步骤

  1. 给CustomLayout添加width参数,默认值设为1200(主网格默认宽度)
  2. 在GridLayout组件中使用传入的width值,而非固定1200
  3. 给包含子网格的容器div设置width样式,确保子GridLayout有正确的可用空间

修改后的组件代码

import "./styles.css";
import GridLayout from "react-grid-layout";
import React from "react";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

// 添加width参数,默认1200
export default function CustomLayout({ layout, onDragStart, onDragStop, width = 1200 }) {
  const [isDraggable, setIsDraggable] = React.useState(true);

  return (
    <GridLayout
      className="layout"
      onDragStart={onDragStart}
      onDragStop={onDragStop}
      layout={layout}
      cols={12}
      rowHeight={80}
      width={width} // 使用传入的width值
      isDraggable={isDraggable}
    >
      {layout.map((item) => {
        if (item.children) {
          // 计算子网格的宽度
          const childWidth = item.w * 67;
          return (
            <div
              onClick={(e) => console.log(e.currentTarget.textContent[0])}
              key={item.i}
              // 设置容器宽度,让子GridLayout能正确使用计算后的宽度
              style={{ background: "pink", border: "1px solid black", width: `${childWidth}px` }}
            >
              <CustomLayout
                layout={item.children}
                width={childWidth} // 传递计算后的宽度给子组件
                onDragStart={() => {
                  setIsDraggable(false);
                }}
                onDragStop={() => {
                  setIsDraggable(true);
                }}
              />
            </div>
          );
        } else {
          return (
            <div
              key={item.i}
              style={{ background: "purple" }}
            >
              {item.i}
            </div>
          );
        }
      })}
    </GridLayout>
  );
}

关键说明

  • 子网格的容器必须设置宽度,否则react-grid-layout会默认占满父容器空间,导致自定义width不生效
  • 递归传递计算后的width给子组件,确保每一层子网格都能使用正确的宽度值
  • 主网格默认使用1200px,子网格按item.w * 67计算宽度,符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:35:57