Search code examples
javascriptreactjsreact-hookslocal-storagereact-grid-layout

Storing layout for my react app in local storage not working


I am working with react-grid-layout and creating some grids which are drag-drop as well as resizable.

So i am able to achieve that and it is working fine.

My UI is like I have two tabs and each tab have some grids, so when I move from one tab two other I am showing that tab's grid.

What I am trying to do

On change of layout I want to store that layout to local storage so that when I refresh or open that tab again the formation of grid should be the one which I changed.

So as per mentioned in library I am using this

  • So what I am doing is when ever onLayoutChange happens I am storing the layout with respect to my active_tab and when I change from one to other tab I am checking Local storage and matching which tab is active and getting that particular layout.
  • But this is not happening it is just taking the basic layout.

What I did

    function getFromLS(key) {
  let ls = {};
  if (global.localStorage) {
    try {
      ls =
        JSON.parse(
          global.localStorage.getItem(localStorage.getItem("active_tab"))
        ) || {};
    } catch (e) {
      /*Ignore*/
    }
    return ls[key];
  }
}
function saveToLS(key, value) {
  if (global.localStorage) {
    global.localStorage.setItem(
      localStorage.getItem("active_tab"),
      JSON.stringify({
        [key]: value
      })
    );
  }
}
  • Onchange function of layout

     const onLayoutChange = (layout, layouts) => {
     saveToLS("layouts", layouts);
     console.log("onchange");
     setlayouts({ layouts });
      };
    

Edit / Update

I have updated my code sandbox as earlier it was taking layouts on console ans undefined now it is taking the layout, Here is the updated code sandbox


Solution

  • The solution is run generateDOM once for each active_menu:

      const [DOM, setDOM] = useState(null)  
    
      useEffect(() => {
        setDOM(generateDOM(data1[active_menu].comp_data))
      }, [data1, active_menu]);
    

    data1 should also be in dependencies because need to recalculate "DOM" when adding and removing elements.

    render:

      <ResponsiveReactGridLayout
        {...props}
        onLayoutChange={(layout, layouts) => onLayoutChange(layout, layouts)}
        layouts={layouts}
        cols={{ lg: 12, md: 4, sm: 6, xs: 4, xxs: 2 }}
      >
        {DOM} 
      </ResponsiveReactGridLayout>  
    

    also I changed localStorage.getItem("active_tab") to active_menu

    codesandbox