question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Combining add/remove with saving grid layout to LS

See original GitHub issue

I am trying to implement the react-grid-layout where I can add/remove grid items and also save the layout to local storage using an individual username as a key. I have tried to implement this but am getting errors which ever way I try it, below is my code for the react grid, could someone advise where I am going wrong…

const ReactGridLayout = WidthProvider(Responsive);

//Find username form localstorage (uuid string)
const username = localStorage.getItem('username')

const Dash = (props) => {
  //Variable used for id of grid component:
  const id = uuid()

  //Hook to set layout state
  const originialLayouts = getLayout("layouts") || {}
  const savedLayout = JSON.parse(JSON.stringify(originialLayouts))
  

  //column size is static
  //layouts taken from local storage via function
  const [ state, setState ] = React.useState({
    cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
    rowHeight: 30,
    layouts: {},
    layout: [].map(function(i, list) {
      return {
        i: i.toString(),
        x: i * 2,
        y: 0,
        w: 3,
        h: 3,
        add: i === (list.length - 1)
      }
    })
  })

  //function ammends layout array with additional grid item
  const addItem = (item) => { 
    console.log('adding: ' + id);
    const newLayout = state.layout;
    newLayout.push({
      i: `${id}`,
      x: (state.layout.length * 3) % (state.cols || 12),
      y: 0,
      w: 3,
      h: 3
    })
    setState({layout: newLayout})
  }

  //function to remove grid item on click
  const removeItem = (i) => {
    console.log(i)
    setState({ layout: _.reject(state.layout, { i:i }) })     
  }

  // function to calculate where to add items based on the cols
  const onBreakpointChange = (breakpoint, cols) => {
    setState({
      cols: cols,
      breakpoint: breakpoint
    })
    console.log(state)
  }

  //function to save layout to LS everytime a grid item is moved.
  const onLayoutChange = (layout, layouts) => {
    saveLayout("layouts", layouts)
    setState({ layout: layout})
  }


  return (
    <div>
      <button onClick={addItem}>Add Item</button>
        <ReactGridLayout
          className="layout"
          layouts={state.layouts}
          breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
          onLayoutChange={(layout, state) => onLayoutChange(layout, state)}
          onBreakpointChange={onBreakpointChange}
          cols={{ lg: 12, md: 12, sm: 6, xs: 4, xxs: 2 }}
          resizeHandles={['s', 'w', 'e', 'n', 'sw', 'nw','se', 'ne']}
          compactType={"vertical"}
          draggableHandle=".dragHandle"               
      >        
        {_.map(state.layout, (item, i) => (
          <div key={item.i} data-grid={state.layout[i]}>            
            <div className='dragHandle'>Drag From Here</div>                        
            <DashItem>
            <button onClick={() => removeItem(item.i)}>Remove Item</button>  
                 <CreateGraph data={state.layout[i]}/>
            </DashItem>
            <div className='dragHandle'>Drag From Here</div>
          </div>
        ))}
        </ReactGridLayout>
    </div>
  );
}

//function to get user layout from LS
const getLayout = (key) => {
  let ls = {};
  if (global.localStorage) {
    try {
      ls = JSON.parse(global.localStorage.getItem(username)) || {};
    } catch (error) {
      console.log('error with getLayout')
    }
  }
  return ls[key]
}

//function to save user layout to LS
const saveLayout = ( key, value ) => {
  if (global.localStorage) {
    global.localStorage.setItem( username, JSON.stringify({ [key]: value}) );
  }
}

export default Dash;

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6

github_iconTop GitHub Comments

2reactions
github-actions[bot]commented, Apr 2, 2021

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this issue will be closed in 7 days

1reaction
lallen-6commented, Mar 24, 2022

Hi,

Yes, I did manage to do this in the end.

I amended the getLayout and saveLayout functions as below:

export const getLayout = (key) => {
  try {
    const serialisedState = localStorage.getItem(key);
    if (serialisedState === null) {
      return [];
    }
    return JSON.parse(serialisedState);
  } catch (error) {
    return [];
  }
};

//function to save user layout to LS
export const saveLayout = (layoutName, state) => {
  try {
    const serialisedState = JSON.stringify(state);
    localStorage.setItem(layoutName, serialisedState);
  } catch (error) {
    console.log("local storage error");
  }
};

So the layout is saved to local storage under a unique key. You can set the local storage layout to update every time it’s changed using the onLayoutChange property of RGL.

You can call the layout back from local storage using a useEffect hook that runs on page load. This will set the layout in state every time the page is loaded i.e.:

// Load layout
  const savedLayout = getLayout(props.id);

  //effect will update the dashlayout when you load page
  React.useEffect(() => {
    setState({
      ...state,
      layout: savedLayout,
    });
  }, []);

  // set state
  const [state, setState] = React.useState({
    cols: { xl: 15, lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
    rowHeight: 100,
    layout: savedLayout,
  });

Hope this helps!

Read more comments on GitHub >

github_iconTop Results From Across the Web

React grid layout - Local storage with add/remove widgets
Therefore, it will call saveToLS() with an empty array of items. You should include a useEffect which will get the layout stored in...
Read more >
[Question] Merge Dynamic Add/Remove with Responsive ...
I want to implement the dynamic add/remove for grid items with saving all current data about position at all breakpoints to local storage....
Read more >
Maintenance Guide for OpenStack® Deployments
This guide contains recovery procedures for StorageGRID Webscale system grid nodes ( ... Use a combination of the following attributes to monitor repairs....
Read more >
Spacemacs documentation
With SPC l s and SPC l L you can save and load layouts to/from a file. Note: By default, Spacemacs will automatically...
Read more >
GNU GRUB Manual 2.06
One of the important features in GRUB is flexibility; GRUB understands filesystems and kernel executable formats, so you can load an arbitrary operating...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found