Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added customBodyRenderLite / removed object deprecation for column values #1339

Merged
merged 3 commits into from
Jun 18, 2020

Conversation

patorjk
Copy link
Collaborator

@patorjk patorjk commented Jun 17, 2020

This PR:

  • Adds customBodyRenderLite to a column's option object.
  • Removes the deprecation warning for object data, as it will now be allowed.

customBodyRenderLite

customBodyRenderLite is a way of rendering data in a more performant way. Using it can lead to tables that render quicker. Before going further, here is a brief technical description of how customBodyRender works under the covers:

  • When setting the table data, it is executed once for every row of data so that the table can get the values for the filterData.
  • When computing the data for the display, it is again executed once for every row (the results are cached in the displayData).

If the data changes, both of the above happen again. This means if you have a table of 1000 rows and 10 columns (all with customBodyRender), A total of 1000 * 10 * 2 = 20,000 function calls get executed related to rendering.

Unlike customBodyRender, the value returned from customBodyRenderLite is not used for filtering. So it's return value has no affect on filters. Instead, filters use the value in the data array. Additionally, unlike customBodyRender, customBodyRenderLite is only called for cells that are visible on the current page. This means for the same table, if you have 10 rows per page, a total of 10 * 10 = 100 function calls get made. A test showing this dynamic has been added.

Another trade off for customBodyRenderLite is that it doesn't take in (value, tableMeta, update), instead it simply takes in (dataIndex, rowIndex). This means you have to lookup a value yourself (though personally I've found having the dataIndex is much more useful).

Objects no longer deprecated

Back in release 2.12.2, a deprecation warning was added stating that objects would no longer be accepted as values for data (with the exception of arrays). This occurred because of this issue: #915. Essentially what was happening was the filter dialog would cause the table to blow up when given object data.

Forbidding objects is overkill though, as being able to input them is extremely useful. I've patched the error that occurred for the filter dialog. There are two basic problems that remain:

  • customBodyRender or customBodyRenderLite is required for object data to be displayed (otherwise the table throws an error). People previously did not seem to have an issue with this ("Deprecated: Passing objects in as data is not supported, and will be prevented in a future release." #1040). I've added a note to the readme about it.
  • Filtering does not work out of the box for object data. Users who want to filter with object data will need to write their own logic. I think I'm fine with this. No one prior to 2.12.2 seemed to inquire about it, and typically these kind of fields are non-text based, so filtering makes no sense anyway.

@@ -865,7 +871,9 @@ class MUIDataTable extends React.Component {
let columnValue = row[index];
let column = columns[index];

if (column.customBodyRender) {
if (column.customBodyRenderLite) {
displayRow.push( column.customBodyRenderLite );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove white space

@@ -134,7 +134,7 @@ function TableBodyCell(props) {
className,
)}
{...otherProps}>
{children}
{typeof children === 'function' ? children(dataIndex, rowIndex) : children}
Copy link
Collaborator

@wdh2100 wdh2100 Jun 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never knew that children could be a function. Interesting.
I thought it was only a react node(element)

Does children mean columns?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's a pattern called "Function as Child Component". It's useful in certain situations. Here the children equal either the value that will be displayed in the column, or the customBodyRenderLite function, which will generate the value for the column.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patorjk thanks!

@patorjk patorjk changed the base branch from master to v3_1_0 June 18, 2020 02:26
@patorjk patorjk merged commit 77170f7 into v3_1_0 Jun 18, 2020
@wdh2100 wdh2100 deleted the customBodyRenderLite branch November 3, 2020 02:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants