Files
bodyshop/_reference/REACT_GRID_LAYOUT_MIGRATION.md

6.3 KiB

React Grid Layout Migration Guide

Current Status: Legacy API (v2.2.2)

What Changed

  • Package Version: 1.3.4 → 2.2.2
  • API Strategy: Using legacy compatibility layer

Migration Completed

Changes Made:

// Before (v1.3.4):
import { Responsive, WidthProvider } from "react-grid-layout";

// After (v2.2.2 with legacy API):
import { Responsive, WidthProvider } from "react-grid-layout/legacy";

Files Updated:

  • src/components/dashboard-grid/dashboard-grid.component.jsx

Why Legacy API?

The v2.x release introduces a completely new hooks-based API with breaking changes. The legacy API provides 100% backward compatibility, allowing us to:

  • Get bug fixes and security updates
  • Maintain existing functionality without code rewrites
  • Plan migration to new API incrementally

Future: Migration to New v2 API

When ready to fully migrate to the modern v2 API, follow this guide:

Breaking Changes in v2

  1. Width Provider Removed

    • Old: WidthProvider(Responsive)
    • New: Use useContainerWidth hook
  2. Props Restructured

    • Old: Flat props structure
    • New: Grouped configs (gridConfig, dragConfig, resizeConfig)
  3. Layout Prop Required

    • Old: Could use data-grid attribute
    • New: Must provide layout prop explicitly
  4. Compaction Changes

    • Old: verticalCompact prop
    • New: compactor prop with pluggable algorithms

Migration Steps

Step 1: Replace WidthProvider with useContainerWidth hook

Before:

const ResponsiveReactGridLayout = WidthProvider(Responsive);

return (
  <ResponsiveReactGridLayout
    className="layout"
    breakpoints={GRID_BREAKPOINTS}
    cols={GRID_COLS}
    layouts={state.layouts}
    onLayoutChange={handleLayoutChange}
  >
    {children}
  </ResponsiveReactGridLayout>
);

After:

import ReactGridLayout, { useContainerWidth, verticalCompactor } from 'react-grid-layout';

function DashboardGridComponent({ currentUser }) {
  const { width, containerRef, mounted } = useContainerWidth();
  
  return (
    <div ref={containerRef}>
      {mounted && (
        <ReactGridLayout
          width={width}
          layout={state.layout}
          gridConfig={{
            cols: 12,
            rowHeight: 30,
            margin: [10, 10]
          }}
          dragConfig={{
            enabled: true,
            handle: '.drag-handle' // optional
          }}
          resizeConfig={{
            enabled: true
          }}
          compactor={verticalCompactor}
          onLayoutChange={handleLayoutChange}
        >
          {children}
        </ReactGridLayout>
      )}
    </div>
  );
}

Step 2: Update Responsive Layouts

For responsive behavior, manage breakpoints manually:

function DashboardGridComponent() {
  const { width, containerRef, mounted } = useContainerWidth();
  const [currentBreakpoint, setCurrentBreakpoint] = useState('lg');
  
  useEffect(() => {
    if (width > 1200) setCurrentBreakpoint('lg');
    else if (width > 996) setCurrentBreakpoint('md');
    else if (width > 768) setCurrentBreakpoint('sm');
    else if (width > 480) setCurrentBreakpoint('xs');
    else setCurrentBreakpoint('xxs');
  }, [width]);

  const currentLayout = state.layouts[currentBreakpoint] || state.layout;
  const currentCols = GRID_COLS[currentBreakpoint];

  return (
    <div ref={containerRef}>
      {mounted && (
        <ReactGridLayout
          width={width}
          layout={currentLayout}
          gridConfig={{
            cols: currentCols,
            rowHeight: 30
          }}
          // ... other props
        >
          {children}
        </ReactGridLayout>
      )}
    </div>
  );
}

Step 3: Update Child Components

The data-grid attribute still works, but explicitly managing layout is preferred:

Before:

<div
  key={item.i}
  data-grid={{
    ...item,
    minH,
    minW
  }}
>
  {content}
</div>

After (Preferred):

// Manage layout in parent state
const layout = state.items.map(item => ({
  i: item.i,
  x: item.x,
  y: item.y,
  w: item.w,
  h: item.h,
  minW: componentList[item.i]?.minW || 1,
  minH: componentList[item.i]?.minH || 1
}));

// Children just need keys
<div key={item.i}>
  {content}
</div>

Step 4: Update Styles (if needed)

The CSS classes remain mostly the same, but check the new documentation for any changes.

Benefits of New API

  • 🚀 Better Performance: Optimized rendering with hooks
  • 📦 TypeScript Support: Full type definitions included
  • 🎯 Better API: More intuitive props organization
  • 🔧 Extensibility: Pluggable compactors and strategies
  • 📱 Modern React: Uses hooks pattern

Testing Checklist

When migrating to new API:

  • Grid items render correctly
  • Drag functionality works
  • Resize functionality works
  • Responsive breakpoints work
  • Layout persistence works
  • Add/remove components works
  • Min/max constraints respected
  • Performance is acceptable
  • No console errors or warnings

Resources


Current Implementation Notes

Component Structure

  • File: src/components/dashboard-grid/dashboard-grid.component.jsx
  • Styles: src/components/dashboard-grid/dashboard-grid.styles.scss
  • Pattern: Responsive grid with dynamic component loading

Key Features Used

  • Responsive layouts with breakpoints
  • Drag and drop
  • Resize handles
  • Layout persistence to database
  • Dynamic component add/remove
  • Min/max size constraints

Configuration

const GRID_BREAKPOINTS = { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 };
const GRID_COLS = { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 };

Performance Considerations

  • Layout changes debounced via database updates
  • Memoized dashboard queries to prevent re-fetches
  • Memoized menu items and layout keys

Last Updated: 2026-01-13
Current Version: react-grid-layout@2.2.2 (legacy API)
Target Version: react-grid-layout@2.2.2 (new API) - Future migration