I am encountering a problem with the library react-grid-layout and I don't know if it's a bug or me doing things badly. I opened an issue here, but the more I think about it, the less it's probable that an issue this big has gone unnoticed. You can find a demo of what i'm experiencing here
What I'm trying to do
I'd like to create a dashboard using react-grid-layout. I'm trying to implement the container pattern so I have a DashboardContainer component controlling the layout via his state and passing this layout down to a Dashboard component in the props.
The problem I encounter
Elements are placed correctly for the initial state but when I add items, the x, y, w and h of the added element aren't correct. It should be (5,0,2,2) for the first addition, and it ends up being placed on (0,4,1,1) I saw that elements can be redimensionned to 1 of width and height if they don't have the correct key, but I think my keys are correct.
Example: this layout is passed to Dashboard layout data
But this is the displayed layout (the element "new0" isn't corresponding) displayed layout
My code
Here is the (simplified) code of my DashboardContainer component
import React from "react";
import ReactDOM from "react-dom";
import Dashboard from "./Dashboard";
class DashboardContainer extends React.Component {
static defaultProps = {
maxRows: 8,
cols: 12
};
state = {
layout: [
{ i: "key0", x: 0, y: 0, w: 2, h: 2 },
{ i: "key1", x: 2, y: 0, w: 3, h: 2 },
{ i: "key2", x: 2, y: 2, w: 2, h: 2 },
{ i: "key3", x: 8, y: 0, w: 3, h: 2 }
],
newElementsCount: 0
};
onLayoutChange = l => {
this.setState({ layout: l });
};
add = () => {
// here we calculate where the new element should be placed
var x = foundX, y = foundY, w = foundW, h = foundH;
var newLayout = this.state.layout;
newLayout.push({
i: "new" + this.state.newElementsCount,
x: x,
y: y,
w: w,
h: h
});
this.setState({
newElementsCount: this.state.newElementsCount + 1,
layout: newLayout
});
};
render() {
return (
<div>
<Dashboard
layout={this.state.layout}
add={this.add}
cols={this.props.cols}
maxRows={this.props.maxRows}
onLayoutChange={this.onLayoutChange}
preventCollision={true}
/>
</div>
);
}
}
const contentDiv = document.getElementById("root");
ReactDOM.render(React.createElement(DashboardContainer), contentDiv);
And here the Dashboard component :
import React from "react";
import RGL, { WidthProvider } from "react-grid-layout";
const ReactGridLayout = WidthProvider(RGL);
class Dashboard extends React.Component {
generateDOM() {
return this.props.layout.map(function(item) {
return <div key={item.i}>{item.i}</div>;
});
}
render() {
return (
<div>
<button onClick={this.props.add}>Add</button>
<ReactGridLayout
rowHeight={30}
maxRows={this.props.maxRows}
cols={this.props.cols}
layout={this.props.layout}
compactType={null}
onLayoutChange={this.props.onLayoutChange}
>
{this.generateDOM()}
</ReactGridLayout>
</div>
);
}
}
module.exports = Dashboard;
The full (nearly) working code can be found in this codesandbox
I'm still very new to React and RGL so any suggestions are welcome !
Thank you