Next.js生产环境下React Data Grid UI崩溃问题求助
Next.js生产环境中React Data Grid UI崩溃问题求助
执行npm run build和npm run start构建部署后,React Data Grid表格UI崩溃,但开发环境(npm run dev)下一切正常,现寻求帮助定位并解决该问题。
状态截图
- 开发环境正常状态:

- 生产环境崩溃状态:

代码示例
"use client"; import { useMemo, useState } from "react"; import { createPortal } from "react-dom"; import { faker } from "@faker-js/faker"; import "../../styles/globals.css"; import DataGrid, { SelectCellFormatter, SelectColumn, textEditor, type Column, type SortColumn, } from "react-data-grid"; const dateFormatter = new Intl.DateTimeFormat("en"); const currencyFormatter = new Intl.NumberFormat("en", { style: "currency", currency: "eur", }); interface SummaryRow { id: string; totalCount: number; yesCount: number; } interface Row { id: number; title: string; client: string; area: string; country: string; contact: string; assignee: string; progress: number; startTimestamp: number; endTimestamp: number; budget: number; transaction: string; account: string; version: string; available: boolean; } function getColumns(direction: any): readonly Column<Row, SummaryRow>[] { return [ SelectColumn, { key: "id", name: "ID", frozen: true, resizable: false, renderSummaryCell() { return <strong>Total</strong>; }, }, { key: "title", name: "Task", frozen: true, renderEditCell: textEditor, renderSummaryCell({ row }) { return `${row.totalCount} records`; }, }, { key: "client", name: "Client", width: "max-content", draggable: true, renderEditCell: textEditor, }, { key: "area", name: "Area", renderEditCell: textEditor, }, { key: "contact", name: "Contact", renderEditCell: textEditor, }, { key: "assignee", name: "Assignee", renderEditCell: textEditor, }, { key: "progress", name: "Completion", renderCell(props) { const value = props.row.progress; return ( <> <progress max={100} value={value} style={{ inlineSize: 50 }} /> {Math.round(value)}% </> ); }, renderEditCell({ row, onRowChange, onClose }) { return createPortal( <div dir={direction} className={"dialogContainerClassname"} onKeyDown={(event) => { if (event.key === "Escape") { onClose(); } }} > <dialog open> <input autoFocus type="range" min="0" max="100" value={row.progress} onChange={(e) => onRowChange({ ...row, progress: e.target.valueAsNumber }) } /> <menu> <button type="button" onClick={() => onClose()}> Cancel </button> <button type="button" onClick={() => onClose(true)}> Save </button> </menu> </dialog> </div>, document.body ); }, editorOptions: { displayCellContent: true, }, }, { key: "startTimestamp", name: "Start date", renderCell(props) { return dateFormatter.format(props.row.startTimestamp); }, }, { key: "endTimestamp", name: "Deadline", renderCell(props) { return dateFormatter.format(props.row.endTimestamp); }, }, { key: "budget", name: "Budget", renderCell(props) { return currencyFormatter.format(props.row.budget); }, }, { key: "transaction", name: "Transaction type", }, { key: "account", name: "Account", }, { key: "version", name: "Version", renderEditCell: textEditor, }, { key: "available", name: "Available", renderCell({ row, onRowChange, tabIndex }) { return ( <SelectCellFormatter value={row.available} onChange={() => { onRowChange({ ...row, available: !row.available }); }} tabIndex={tabIndex} /> ); }, renderSummaryCell({ row: { yesCount, totalCount } }) { return `${Math.floor((100 * yesCount) / totalCount)}% ✔️`; }, }, ]; } function rowKeyGetter(row: Row) { return row.id; } function createRows(): readonly Row[] { const now = Date.now(); const rows: Row[] = []; for (let i = 0; i < 1000; i++) { rows.push({ id: i, title: `Task #${i + 1}`, client: faker.company.name(), area: faker.person.jobArea(), country: faker.location.country(), contact: faker.internet.exampleEmail(), assignee: faker.person.fullName(), progress: Math.random() * 100, startTimestamp: now - Math.round(Math.random() * 1e10), endTimestamp: now + Math.round(Math.random() * 1e10), budget: 500 + Math.random() * 10500, transaction: faker.finance.transactionType(), account: faker.finance.iban(), version: faker.system.semver(), available: Math.random() > 0.5, }); } return rows; } type Comparator = (a: Row, b: Row) => number; function getComparator(sortColumn: string): Comparator { switch (sortColumn) { case "assignee": case "title": case "client": case "area": case "country": case "contact": case "transaction": case "account": case "version": return (a, b) => { return a[sortColumn].localeCompare(b[sortColumn]); }; case "available": return (a, b) => { return a[sortColumn] === b[sortColumn] ? 0 : a[sortColumn] ? 1 : -1; }; case "id": case "progress": case "startTimestamp": case "endTimestamp": case "budget": return (a, b) => { return a[sortColumn] - b[sortColumn]; }; default: throw new Error(`unsupported sortColumn: "${sortColumn}"`); } } function Home() { const [rows, setRows] = useState(createRows); const [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]); const [selectedRows, setSelectedRows] = useState( (): ReadonlySet<number> => new Set() ); const columns = useMemo(() => getColumns("ltr"), []); const summaryRows = useMemo((): readonly SummaryRow[] => { return [ { id: "total_0", totalCount: rows.length, yesCount: rows.filter((r) => r.available).length, }, ]; }, [rows]); const sortedRows = useMemo((): readonly Row[] => { if (sortColumns.length === 0) return rows; return [...rows].sort((a, b) => { for (const sort of sortColumns) { const comparator = getComparator(sort.columnKey); const compResult = comparator(a, b); if (compResult !== 0) { return sort.direction === "ASC" ? compResult : -compResult; } } return 0; }); }, [rows, sortColumns]); const gridElement = ( <DataGrid rowKeyGetter={rowKeyGetter} columns={columns} rows={sortedRows} defaultColumnOptions={{ sortable: true, resizable: true, }} selectedRows={selectedRows} onSelectedRowsChange={setSelectedRows} onRowsChange={setRows} sortColumns={sortColumns} onSortColumnsChange={setSortColumns} topSummaryRows={summaryRows} bottomSummaryRows={summaryRows} className="fill-grid" direction="ltr" /> ); return ( <div> <div className={"toolbarClassname"}></div> {gridElement} </div> ); } export default Home;
已尝试操作
- 确认
npm run dev本地运行一切正常 - 确认问题仅在部署后出现,本地开发无此问题
预期结果
- 生产环境下的表现与本地开发环境一致
环境信息
- React版本:18
- Next.js版本:14.1.0
- react-data-grid版本:7.0.0-beta.42
- 包管理器:npm
内容的提问来源于stack exchange,提问作者Abin Das
相关产品推荐
相关产品推荐

