I'm creating a React project using react-grid-layout. I can create multiple grids via click on a Button in App JS:
import "./styles.css";
import { useState } from "react";
import Grid from "./Grid";
import Button from "./Button";
export default function App() {
const [wrappersArray, setWrappersArray] = useState([]);
const [idCounter, setIdCounter] = useState(0);
const [elemsList, setElemsList] = useState({ // my layout
0: [
{ i: "b", x: 0, y: 0, w: 1, h: 1 },
{ i: "k", x: 0, y: 0, w: 1, h: 1 }
],
1: [
{ i: "b", x: 0, y: 0, w: 1, h: 1 },
{ i: "k", x: 0, y: 0, w: 1, h: 1 }
],
2: [
{ i: "b", x: 0, y: 0, w: 1, h: 1 },
{ i: "k", x: 0, y: 0, w: 1, h: 1 }
]
});
console.log("elems list", elemsList);
return (
<div className="App">
<div style={{ border: "1px solid #000", padding: "20px" }}>
<Grid
layout={elemsList[idCounter]}
setElemsList={setElemsList}
idCounter={idCounter}
/>
<Button setElemsList={setElemsList} idCounter={idCounter} />
</div>
{wrappersArray}
<button // btn to create new grid
style={{ margin: "20px 0 0 0" }}
onClick={() => {
setWrappersArray(
wrappersArray.concat( // creating new grids with unique IDs (idCounter is ID)
<div
style={{ border: "1px solid #000", padding: "20px" }}
key={idCounter}
>
<Grid
layout={elemsList[idCounter]}
setElemsList={setElemsList}
idCounter={idCounter}
/>
<Button setElemsList={setElemsList} idCounter={idCounter} />
</div>
)
);
setIdCounter(idCounter + 1); // incrementing ID to make it unique (it also matches the index in elemsList)
}}
>
add grid
</button>
</div>
);
}
In Grid component i set my layouts via onDragStop and onLayoutChange handlers:
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,
setElemsList,
idCounter
}) {
return (
<GridLayout
className="layout"
onDragStart={onDragStart}
onDragStop={(newLayout) => {
setElemsList((prevState) => ({
...prevState,
[idCounter]: newLayout
}));
}}
onLayoutChange={(newLayout) => {
setElemsList((prevState) => ({
...prevState,
[idCounter]: newLayout
}));
}}
layout={layout}
cols={24}
rowHeight={80}
width={1600}
>
{layout.map((item) => {
return (
<div key={item.i} style={{ background: "purple", color: "#fff" }}>
{item.i}
</div>
);
})}
</GridLayout>
);
}
Finally, in Button component i just add new element to certain grid:
export default function Button({ setElemsList, idCounter }) {
const newItem = {
x: 0,
y: 0,
w: 1,
h: 1,
i: "test" + Math.floor(Math.random() * 90000) + 10000
};
return (
<button
onClick={() => {
setElemsList((prevState) => ({
...prevState,
[idCounter]: [...prevState[idCounter], newItem] // add to certain grid
}));
}}
>
Add elem
</button>
);
}
The issue is - if I create a new Grid and then try to add new elem to previous one, it won't work. What did I do wrong?
P.S. my codesandbox is here: https://codesandbox.io/s/modest-cori-qxvpkx?file=/src/Button.jsx:0-417