Material-table: Frequent data changes MaterialTable crashes client while rendering (memory leak from DataManager.js)

Created on 24 Nov 2020  路  13Comments  路  Source: mbrn/material-table

Hello Material Team,

I'm trying to implement a MaterialTable which can render with new state frequently. The data will be 0-300 items. I'm using most of the default functionality like selecting, export, pagination etc. . therefore I don't want to switch to remote data. When I toggle data 5-6 times the client crashes. See this example:
https://codesandbox.io/s/zen-cohen-mqh0c?file=/src/TableComponent.js

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Click "No Data" then "Dummy Data"
  2. repeat first step 15 times every second.

Expected behavior
Table data will be rendered quickly the first clicks. After a while the client crashes. Same behavior on Chrome, Firefox, Edge.

Additional context
I created an similar example where just new Data is created with rect table.
This is working flawlessly:
https://codesandbox.io/s/practical-agnesi-32ch2?file=/src/App.js

Atm I'm doing a workaround with window.location.reload(true); . It is working since i cache the data in a cookie. But it is not nice.

Thanks in advance for advise or bugfix.
Samurus

Edit: I downgraded several versions from 1.69.2 down to 1.20.0 and get same results.
Edit 2: Downgrading to 1.68.0 fixed the issue only in demo project. My example breaks as soon as I use 2+ columns.
Used this code to try out in demo.js:468 project:
onClick={() => {
this.setState({data: []})
}}
>
no data

onClick={() => {
this.setState({data:[
{id: 1,name: "A1",surname: "B",isMarried: true,birthDate: new Date(1987, 1, 1),birthCity: 0,sex: "Male",type: "adult",insertDateTime: "1994-11-23T08:15:30-05:00",time: new Date(1900, 1, 1, 14, 23, 35),},
{
id: 2,name: "A2",surname: "B",isMarried: false,birthDate: new Date(1987, 1, 1),birthCity: 34,sex: "Female",type: "adult",insertDateTime: "1994-11-05T13:15:30Z",time: new Date(1900, 1, 1, 14, 23, 35),parentId: 1,
}
]})
}}
>
dummy data

bug

Most helpful comment

Hey @Samurus had the same problem, downgrade material-table to version 1.67.1 solved the problem for me. But still I think to this is something what should be fixed

All 13 comments

Just saw this issue in a codebase that uses this library, this seems like a memory leak related to the data-manager modifying the columns prop in this method -> src/utils/data-manager.js. In your sandbox you can see (inspect/log) the prop columns having the tableData field even as you don't provide it, with a couple of clicks the width and initialWidth of columns.tableData will easy reach mb size in a couple of clicks, not that familiar with this repo to submit a fix.

Thanks for that hint. I have tryed editing that component somehow but my beginner react level seems to be not enough. Is there some kind of easy workaround for my example code?

Hey @Samurus had the same problem, downgrade material-table to version 1.67.1 solved the problem for me. But still I think to this is something what should be fixed

I have same issue here.

My only work arounds so far, since I think you cannot override "DataManager" and fix it locally (see line 19 https://github.com/mbrn/material-table/blob/master/src/material-table.js).
a) Storing state in some local storage instead of props and forcing refresh with window.location.reload(true);.
b) Chaning to 1.67.0 (only worked on demo-project by thix repo).
c) Using other Library. Currently trying out MUI > https://blog.bitsrc.io/top-5-react-table-libraries-170505f75da7
d) Reduce column size to 1. This is nonsense since you dont have a table anymore.

New workaround: Setting columns directly as mentioned in https://github.com/mbrn/material-table/issues/2650 works for me:
columns={[
{
title: "id",
field: "articleId",
hidden: true,
cellStyle: { width: 150, minWidth: 150 }
},
{
title: "name",
field: "product.name",
editable: "never",
cellStyle: { width: 150, minWidth: 150 }
}
]}

Update: Downside of this workaround is that editing cells will cause reset of filter/sorting.

Hey ;)

is there someone who is trying to fix it ? just to know if i should take a look.. it's a huge leak and a lot of people use dynamics columns... and i can't downgrade to a working version because we need jsPDF part.

It's been 14 days since it was open....

@peacechen mentioned other related tickets: #2451 #2685 #2650 #2643 #2581 #2514 #2486
Might be a huge impact fix.

@Samurus
I submitted PR #2689 to fix the bug causing the freeze up.

@peacechen thank you for your PR. I attempted to test it locally, got this error:

SyntaxError: .../dist/utils/data-manager.js: Support for the experimental syntax 'classProperties' isn't currently enabled (5:16):

  3 | 
  4 | export default class DataManager {
> 5 |   applyFilters = false;
    |                ^
  6 |   applySearch = false;
  7 |   applySort = false;
  8 |   currentPage = 0;

Add @babel/plugin-proposal-class-properties (https://git.io/vb4SL) to the 'plugins' section of your Babel config to enable transformation.

First of all thanks for taking a look into this @peacechen @RELNO!

I managed to reproduce that behavior and get same error message. I'm kinda new to React and dont know how the release is built/compiled but here are some findings:
Reproducing: replace data-manager.js in local project with changes from PR. Starting will result as you described.
I wonder how the release is built. When im trying to reproduce the memory leak on original sources in demo project I cannot do. But I can reproduce it with all releases. So it might be related to the release building process.
The compiled data-manager.js in release build starts with following which would explain the error message:
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

My hope: The PR will still fix things:)

Let's move this into the PR's conversation thread.

The babel error won't be an issue when this is published because @mbrn transpiles the code. Look in node_modules/material-table and you'll see only a dist folder (no src dir). I've been testing it by running npm run build from my fork and copying the dist folder over to node_modules.

Ah I just figured how to do it. 1. Download Master. 2. Apply your changes. 3. run "build": "babel src --out-dir dist", from package.json 4. replace npm_module files with dist files. 5. Test and succeed! cheers
Thanks again. Now I don't even need to wait for new release. Keeping ticket open until its merged:)

Was this page helpful?
0 / 5 - 0 ratings