React grid layout resets local storage when dynamically generated cards

53 Views Asked by At

I am dynamically getting data from backend and converting them to cards, These cards are draggable and also resizable When I change the layout (say by dragging a card to different location), my local storage is updated perfectly When I refresh the page, the layout is changed/resetted,even in local storage

  useEffect(() => {
  fetchCharts();
  }, []);

  // related to react grid layout
  const [state, setState] = useState({
    layouts: JSON.parse(JSON.stringify(originalLayouts)),
  });

  const resetLayout = () => {
    setState({ layouts: {} });
  };

 const onLayoutChange = (layout, layouts) => {
if(!isLoading){

  console.log(layouts)
  saveToLS("layoutsInventory", layouts);
  console.log('Lauyots' ,layouts);
  setState({ layouts });
 }
};

These functions are above component

function getFromLS(key) {
  console.log(key)
  let ls = {};
  if (global.localStorage) {
  try {
  ls = JSON.parse(global.localStorage.getItem("rgl-Inventory")) || {};
 } catch (e) {
  /*Ignore*/
  console.log(e)
 }
}
console.log(ls[key])
return ls[key];
}

//Set to local storage- layout
function saveToLS(key, value) {
if (global.localStorage) {
global.localStorage.setItem(
  "rgl-Inventory",
  JSON.stringify({
    [key]: value,
  })
 );
}
 }

My imports

import { WidthProvider, Responsive } from "react-grid-layout";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

const ResponsiveReactGridLayout = WidthProvider(Responsive);
const originalLayouts = getFromLS("layoutsInventory") || {};

My localstorage Local Storage

My local storage when I change the position of one card, therefore layout is changed also in Local storage When layout is changed

now when I refresh the page it is again changed to first image,which shouldn't happen

My whole code

import { useEffect, useState } from "react";
import ToastMsg from "../UI/ToastMsg";
import { toast } from "react-toastify";
import NautoChart from "./NautoChart";

import { WidthProvider, Responsive } from "react-grid-layout";
import "react-grid-layout/css/styles.css";
import "react-resizable/css/styles.css";

const ResponsiveReactGridLayout = WidthProvider(Responsive);
const originalLayouts = getFromLS("layoutsInventory") || {};

const options = {
  maintainAspectRatio: false,
  elements: {},
  layout: {
    autoPadding: true,
  },
  plugins: {
    legend: {
      display: false,
      position: "left",
      labels: {
        usePointStyle: true,
        pointStyle: "circle",
        padding: 16,
      },
    },
  },
};

//Get from local storage- layout
function getFromLS(key) {
  console.log(key)
  let ls = {};
  if (global.localStorage) {
    try {
      ls = JSON.parse(global.localStorage.getItem("rgl-Inventory")) || {};
    } catch (e) {
      /*Ignore*/
      console.log(e)
    }
  }
  console.log(ls[key])
  return ls[key];
}

//Set to local storage- layout
function saveToLS(key, value) {
  if (global.localStorage) {
    global.localStorage.setItem(
      "rgl-Inventory",
      JSON.stringify({
        [key]: value,
      })
    );
  }
}

const ChartDisplay = () => {
  const [data, setData] = useState(null);
  const [isLoading, setIsLoading] = useState(true)
  const fetchCharts = async () => {
    
    try {
      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_DOMAIN}/nautobot/charts/chart`,
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ method: "get" }),
        }
      );

      if (response.ok) {
        const responseData = await response.json();
        setData(responseData.results);
      } else {
        throw new Error(`Failed To fetch, Retry: ${response.status}`);
      }
    } catch (error) {
      const err = error.message || error.Error || error;
      console.error("Error fetching data:", err);
      const errorToast = () => {
        toast.error(<ToastMsg message={err} />, {
          hideProgressBar: true,
          progress: undefined,
        });
      };
      errorToast();
      // You can also set an error state here if needed
    }

    finally{
      setIsLoading(false)
    }
  };

  useEffect(() => {
    fetchCharts();
  }, []);

  // related to react grid layout
  const [state, setState] = useState({
    layouts: JSON.parse(JSON.stringify(originalLayouts)),
  });

  const resetLayout = () => {
    setState({ layouts: {} });
  };

  const onLayoutChange = (layout, layouts) => {
    if(!isLoading){

      console.log(layouts)
      saveToLS("layoutsInventory", layouts);
      console.log('Lauyots' ,layouts);
      setState({ layouts });
    }
  };
  // related to react grid layout

  return (
    <>
      {console.log('Layouts state',state.layouts)}

      <div className='w-full px-4 sm:px-8 bg-red-500'>
        <button onClick={() => resetLayout()}>Reset Layout</button>

        <ResponsiveReactGridLayout
          useCSSTransforms={false}
          draggableHandle=".drag-handle"
          className="layout"
          // margin={[80,80]}
          cols={{ lg: 24, md: 20, sm: 12, xs: 8, xxs: 4 }}
          // containerPadding={{lg:[30,30],}}
          rowHeight={30}
          layouts={state.layouts}
          onLayoutChange={(layout, layouts) => onLayoutChange(layout, layouts)}
        >
          {/* <div className="w-full mxsm:px-2 msm:px-4 sm:px-8 grid grid-cols-2 gap-4"> */}
            {data?.map((el,index) => {
              
              return ( <div
                  key={el.id}
                  // key={index.toString()}
                  className="border border-gray-200  rounded-xl shadow-sm overflow-clip"
                  data-grid={{ w: 10, h: 7, x: 0, y: 0 }}
                >
                  <NautoChart
                    chartData={el.chart}
                    options={options}
                  />
                  
                </div>
              );
            })}
          {/* </div> */}
        </ResponsiveReactGridLayout>
      </div>
    </>
  );
};

export default ChartDisplay;
0

There are 0 best solutions below