fix: dynamic import react-grid-layout to avoid SSR crash
WidthProvider is not available during SSR. Use dynamic import inside useEffect to load it only on the client side. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
79c144d74b
commit
b222429475
|
|
@ -1,9 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo, useState, useEffect } from 'react';
|
||||||
import { Responsive } from 'react-grid-layout';
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
||||||
const WidthProvider = require('react-grid-layout').WidthProvider;
|
|
||||||
import { useAppSelector } from '@/adapters/state/redux/store';
|
import { useAppSelector } from '@/adapters/state/redux/store';
|
||||||
import { useLayout } from '@/frameworks/hooks/useLayout';
|
import { useLayout } from '@/frameworks/hooks/useLayout';
|
||||||
import { ChartWrapper } from '@/frameworks/components/charts/ChartWrapper';
|
import { ChartWrapper } from '@/frameworks/components/charts/ChartWrapper';
|
||||||
|
|
@ -13,8 +10,6 @@ import { useUIStore } from '@/adapters/state/zustand/uiStore';
|
||||||
import 'react-grid-layout/css/styles.css';
|
import 'react-grid-layout/css/styles.css';
|
||||||
import 'react-resizable/css/styles.css';
|
import 'react-resizable/css/styles.css';
|
||||||
|
|
||||||
const ResponsiveGridLayout = WidthProvider(Responsive);
|
|
||||||
|
|
||||||
/** Placeholder shown when the canvas is empty. */
|
/** Placeholder shown when the canvas is empty. */
|
||||||
function DropZonePlaceholder() {
|
function DropZonePlaceholder() {
|
||||||
const setImportModalVisible = useUIStore((s) => s.setImportModalVisible);
|
const setImportModalVisible = useUIStore((s) => s.setImportModalVisible);
|
||||||
|
|
@ -46,6 +41,17 @@ function DropZonePlaceholder() {
|
||||||
export function CenterCanvas() {
|
export function CenterCanvas() {
|
||||||
const charts = useAppSelector((s) => s.chart.charts);
|
const charts = useAppSelector((s) => s.chart.charts);
|
||||||
const { layouts, onLayoutChange } = useLayout();
|
const { layouts, onLayoutChange } = useLayout();
|
||||||
|
const [GridLayout, setGridLayout] = useState<any>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
import('react-grid-layout').then((mod: any) => {
|
||||||
|
const WP = mod.WidthProvider || mod.default?.WidthProvider;
|
||||||
|
const Resp = mod.Responsive || mod.default?.Responsive;
|
||||||
|
if (WP && Resp) {
|
||||||
|
setGridLayout(() => WP(Resp));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const gridLayouts = useMemo(() => {
|
const gridLayouts = useMemo(() => {
|
||||||
return layouts.map((item) => ({
|
return layouts.map((item) => ({
|
||||||
|
|
@ -73,9 +79,13 @@ export function CenterCanvas() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GridLayout) {
|
||||||
|
return <div style={{ padding: 16 }}>加载中...</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: 16, minHeight: '100%' }}>
|
<div style={{ padding: 16, minHeight: '100%' }}>
|
||||||
<ResponsiveGridLayout
|
<GridLayout
|
||||||
className="layout"
|
className="layout"
|
||||||
layouts={{ lg: gridLayouts }}
|
layouts={{ lg: gridLayouts }}
|
||||||
breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
|
breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
|
||||||
|
|
@ -91,7 +101,7 @@ export function CenterCanvas() {
|
||||||
<ChartWrapper chartId={chart.id} />
|
<ChartWrapper chartId={chart.id} />
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</ResponsiveGridLayout>
|
</GridLayout>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue