We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

The instructions for rendering a react component in column cause a memory leak

Hi,

We are using the TreeGrid component in a React app. We render some of the table cells using React components, following the instructions here:

https://ej2.syncfusion.com/react/documentation/treegrid/how-to/render-react-component-in-column/ 

The problem is that these components rendered with ReactDOM.render never get removed. So after looking at a few tables, we can end up with thousands of these components hanging around. At some point, ReactDOM.unmountComponentAtNode should be called for these componets. However, since we have no callback for when the cell is removed, there is no place to add this cleanup.

So, my questions:

  1. Is there a good way to unmount these rendered cells?
  2. Is there a better way of rendering React components in cells?

Jeff

8 Replies

JW Jeff Williams October 5, 2022 06:39 AM

A simple example:

- 2 sets of data, with a button to switch between them

- one cell rendered using a react component that just bolds the text


import {
  ColumnDirective,
  ColumnsDirective,
  TreeGridComponent,
} from '@syncfusion/ej2-react-treegrid'
import React from 'react'
import * as ReactDOM from 'react-dom'


const datasets = [
  [{ id: 'Norway' }, { id: 'Sweden' }],
  [{ id: 'France' }, { id: 'Spain' }],
]


interface BoldProps {
  id: string
}


const Bold = ({ id }: BoldProps): JSX.Element => {
  return <b>{id}</b>
}


export const Test = (): JSX.Element => {
  const [dataset, setDataset] = React.useState(0)
  const data = datasets[dataset]


  const updateData = (): void => {
    setDataset((dataset + 1) % datasets.length)
  }


  const queryCellInfo = (args: any): void => {
    if (args.column.field === 'component') {
      ReactDOM.render(<Bold id={args.data.id} />, args.cell)
    }
  }


  return (
    <>
      <button onClick={updateData}>Update Data</button>
      <TreeGridComponent dataSource={data} queryCellInfo={queryCellInfo}>
        <ColumnsDirective>
          <ColumnDirective key={0} field={'id'} headerText={'Name'} />
          <ColumnDirective
            key={0}
            field={'component'}
            headerText={'Component'}
          />
        </ColumnsDirective>
      </TreeGridComponent>
    </>
  )
}

After initial render:

syncfusion1.jpg


You can see that there are already 4 Bold components.

After clicking on Update Data to change the data:

syncfusion2.jpg


The original 4 Bold componets are there, along with 2 new components (for France and Spain).

Clicking on Update Data again to switch back to the original data:

syncfusion3.jpg


As you can see, for every render of cells in the component column, a new react component is added and never goes away! We have tables with hundreds of rows and multiple rendered cells, so this is a real problem.

 



PS Pon Selva Jeganathan Syncfusion Team October 6, 2022 11:14 PM

Hi Jeff,


Thanks for contacting syncfusion forum.


We are working on this query with high priority. We need time to validate the issue. So, we will update further details on or before 11th October 2022. Until then we value your patience. In the meanwhile, we will contact if any details are required.


Regards,
Pon selva



PS Pon Selva Jeganathan Syncfusion Team October 10, 2022 01:18 PM

Hi Jeff,


Thanks for your patience.


Query:  The problem is that these components rendered with ReactDOM.render never get removed

We checked your query by preparing sample (based on your code snippet), but we were unable to replicate the issue at our end.


Please refer to the sample,

https://stackblitz.com/edit/demo-react-functional-stateful-component-mcsdxe?file=datasource.js,index.js


Please refer to the video demo,

https://www.syncfusion.com/downloads/support/directtrac/general/7z/Demo1764965069


If you still facing issue after trying the above method, please provide the following information


  1. Treegrid package version details.
  2. Video demo of the issue or screenshot of the issue and share the stacktrace details (if face any)
  3. Try to replicate the issue in our shared sample or share the issue reproducible sample.


The requested information will be helpful to proceed further


Regards,

Pon selva



JW Jeff Williams October 12, 2022 06:07 AM

Hi,


The demo above did not really check if the components are being left behind. You can use the Components view in React dev tools to see this, see the 'react-components.mp4' video to see this.


I also created an edited version of the sample:

https://stackblitz.com/edit/demo-react-functional-stateful-component-dzmja3?file=datasource.js,index.js


Here I gave each Bold component a unique Id (and changed the old id field to be called name). Then I added an effect to the Bold component to log information about itself every 5s. You can see in the video 'component-logs.mp4' that _all_ of the components (even those no longer displayed) are logging every 5s. This is because they are still running in memory.


Note that this has nothing to do with the Treegrid package version. This is because ReactDOM.render is being used with no corresponding ReactDOM.unmountComponentAtNode.




Attachment: videos_31c59f52.zip


PS Pon Selva Jeganathan Syncfusion Team October 14, 2022 12:46 AM

Hi Jeff,


Thanks for the update.


We are working on this query with high priority. We need time to validate the issue. So, we will update further details on or before 17th October 2022. Until then we value your patience. In the meanwhile, we will contact if any details are required.


Regards,

Pon selva   



PS Pon Selva Jeganathan Syncfusion Team October 17, 2022 11:03 AM

Hi Jeff,


Thanks for your patience.


By analyzing your code example, this issue occurred while rendering the react component in the queryCellInfo event of the grid. 

 

We suggest you use ColumnTemplate features to render the react component in Tree Grid columns instead of the queryCellInfo event.


Please refer to the below sample,

https://stackblitz.com/edit/demo-react-functional-stateful-component-44ra2n?file=datasource.js,index.js


Please refer to the below help documentation,

https://ej2.syncfusion.com/react/documentation/treegrid/columns/column-template/


Please refer to the below demo,

https://ej2.syncfusion.com/react/demos/#/bootstrap5/treegrid/columntemplate


Note: If you change the dataSource continuously, it will take some time to clear all the template elements from the DOM.


Kindly get back to us for further assistance.


Regards,

Pon selva   


If this post is helpful, please consider Accepting it as the solution so that other members can locate it more quickly.




JW Jeff Williams October 21, 2022 03:44 AM

Hi,


This is quite a big change, so I'll need some time to test. However, it may be a good idea to update the documentation at:

https://ej2.syncfusion.com/react/documentation/treegrid/how-to/render-react-component-in-column/ 

Since that method is problematic.





FS Farveen Sulthana Thameeztheen Basha Syncfusion Team October 24, 2022 05:51 AM

Hi Jeff Williams,


As per your request, we will add this limitation in our documentation section. We will let you know once it is refreshed.


Please get back to us if you need any further assistance. We are happy to assist you further.


Regards,

Farveen sulthana T


Loader.
Live Chat Icon For mobile
Up arrow icon