AgGrid 在 React 应用程序中重新渲染时崩溃

AgGrid crashes on re-render in React application

我有一个使用 AgGrid 显示数据的 React + Typescript 应用程序。数据从服务器获取,然后馈送到 AgGrid,我们有多个选项可供用户交互,这些选项可能会更改显示的数据,例如过滤器、分页和其他一些自定义内容。

显示的数据是先抓取,然后完整显示。例如,我们获取 25 行并显示所有行,我们没有使用 AgGrid 的任何分页功能。

如果用户对其中一个参数进行了更改,而数据没有更改(例如,添加一个过滤器来捕获已显示的每个项目),则数据将被重新获取,然后再次馈送到 AgGrid,但这会导致 AgGrid 崩溃。

只有当数据没有改变时才会发生这种情况。

发生的错误如下:

The above error occurred in the <AgGridReact> component:
    in AgGridReact (at ag-collections/index.tsx:250)
    in div (at ag-collections/index.tsx:240)
    in div (created by ForwardRef(Paper))
    in ForwardRef(Paper) (created by WithStyles(ForwardRef(Paper)))
    in WithStyles(ForwardRef(Paper)) (at ag-collections/index.tsx:225)
    in main (at main/index.tsx:59)
    in div (at main/index.tsx:36)
    in Component (created by WithStyles(Component))
    in WithStyles(Component) (at ag-collections/index.tsx:218)
    in TableAg (created by Context.Consumer)
    in Connect(TableAg) (created by Connect(TableAg))
    in Connect(TableAg) (created by Context.Consumer)
    in withRouter(Connect(TableAg)) (created by WithStyles(withRouter(Connect(TableAg))))
    in WithStyles(withRouter(Connect(TableAg))) (created by Context.Consumer)
    in Route (at routes.tsx:20)
    in Switch (at routes.tsx:16)
    in Routes (at app.tsx:50)
    in ThemeProvider (at app.tsx:48)
    in Route (created by QueryParamProvider)
    in QueryParamProvider (at app.tsx:47)
    in Provider (at app.tsx:46)
    in App (at src/index.tsx:8)
    in Router (created by HashRouter)
    in HashRouter (at src/index.tsx:7)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit <link removed> to learn more about error boundaries. index.js:1437
TypeError: can't define property "areEquivPropertyTracking": Array is not extensible
changeDetectionService.js:147
TypeError: can't define property "areEquivPropertyTracking": Array is not extensible

changeDetectionService.js 中有问题的行是:

      if (newA) {
        a.areEquivPropertyTracking = []; // LINE 147
      } else if (a.areEquivPropertyTracking.some(function (other) {
        return other === b;
      })) return true;

      if (newB) {
        b.areEquivPropertyTracking = [];
      } else if (b.areEquivPropertyTracking.some(function (other) {
        return other === a;
      })) {
        return true;
      }

据我所知,他们正试图在对象 a 上创建一个新项目,但这是被禁止的。

如果我需要提供其他任何东西,我可以尝试这样做。我该如何解决这个问题?

如果提供的数据是不可变的,那么您将无法执行深度检查,因为这会尝试扩展提供的对象。

但是,可以使用多种数据变化检测策略。

我通过将以下内容添加到 AgGridReact 组件解决了这个问题:

import { ChangeDetectionStrategyType } from 'ag-grid-react/lib/changeDetectionService'
...
<AgGridReact
rowDataChangeDetectionStrategy={ChangeDetectionStrategyType.IdentityCheck}
...
/>

这就足够了。

@benhodeda 的 this github 回答让我想到了这个,上面写着:

hi :) I had a similar problem when I've migrated our state object to use immer instead of immutableJS . We bind the state to AgGridReact's rowData prop, and when we filter the data (server-side filtering) the app was crash while doing change detection. I added deltaRowDataMode prop alongside with getRowNodeId={row => row.id} on AgGridReact component.

you can read more here: https://www.ag-grid.com/javascript-grid-data-update/

这也可以通过将 immutableData 属性设置为 true 来处理 - 然后网格将默认使用 ChangeDetectionStrategyType.IdentityCheck 作为 rowDataChangeDetectionStrategy

有关更多信息,请参阅 AG Grid 文档: https://www.ag-grid.com/react-data-grid/fine-tuning/#row-data-control https://www.ag-grid.com/react-data-grid/immutable-data/