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 } ] } ] } ];
解决方案
问题核心两点:
- 组件未接收并使用传入的
widthprops,硬编码固定值1200 - 子网格的容器div未限制宽度,导致子
GridLayout无法应用自定义宽度
修改步骤
- 给
CustomLayout添加width参数,默认值设为1200(主网格默认宽度) - 在
GridLayout组件中使用传入的width值,而非固定1200 - 给包含子网格的容器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
相关产品推荐
相关产品推荐

