react-grid-layout: saving layout to db, mapping grid children w/ layout on page load

889 Views Asked by At

I'm using react-grid-layout for a simple, single-column music playlist with "draggable" ordering.

I'm able to successfully save the layout object to Firestore onDragStop, and successfully retrieve the updated layout object at page load, but can't seem to map my children correctly.

I'm mapping my grid children in useEffect like below but can't get my indexing right, even though the layout object logs correctly.

  useEffect(() => {
    let mounted = true;
    if (mounted && songs && layout) {
      setAlbumSongs(
        songs.map((sng, i) => (
          <div key={`${layout[i].y}`}> // `i` doesn't work either
            <Song
              song={songs[layout[i].y]} // sng also does not work
              onHandlePlay={onHandlePlay}
              ref={audioPlayerRef}
            />
          </div>
        )),
      );
    }
    return () => (mounted = false);
  }, []);

My render is this:

  return (
    <GridLayout
      cols={1}
      className="song-list"
      layout={layout}
      width={268}
      rowHeight={189}
      isResizable={false}
      margin={[0, 10]}
      onDragStop={(newLayout) => onDragStop(newLayout)} // sends newLayout to parent for db saving
    >
      {albumSongs}
    </GridLayout>
  );
1

There are 1 best solutions below

0
On

I don't know how it worked, but using the WithProvider HOC made it magically work.

I was previously importing GridLayout like this:

import GridLayout from 'react-grid-layout'; // wrong

I saw in the demo for saving layout to LocalStorage that they imported it like this:

import RGL, { WidthProvider } from 'react-grid-layout'; // correct

...and then inside my functional component, pass RGL to WithProvider like this:

const GridLayout = WithProvider(RGL);

Then use as normal:

  return (
    <GridLayout
      cols={1}
      className="song-list"
      layout={layout}
      width={268}
      rowHeight={189}
      isResizable={false}
      margin={[0, 10]}
      onDragStop={(newLayout) => onDragStop(newLayout)} // sends newLayout to parent for db saving
    >
      {albumSongs}
    </GridLayout>
  );