React-grid-layout - can't add new grid item

275 Views Asked by At

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

0

There are 0 best solutions below