Skip to content
This repository has been archived by the owner on Jun 25, 2020. It is now read-only.

fix(legacy-table): avoid React DOM #392

Merged
merged 9 commits into from
Mar 9, 2020

Conversation

ktmud
Copy link
Contributor

@ktmud ktmud commented Mar 7, 2020

jquery.datatables will manipulate DOMs, sometimes remove them. In case of component being reloaded with updated props, React will not be able to find those removed nodes, causing a cannot removeChild error.

Because of the the way to assign row keys, if table shape changes (add or remove columns), React may also have difficulty match the cached nodes via keys.

In general it's a bad idea to directly manipulate React rendered DOM nodes, so we better just let jquery.datatables handle everything.

In the future, once we removed jquery.datatables, a pure React component will not have such issues.

This PR also contains a fix to null percent_metrics.

cc @kristw @etr2460

🐛 Bug Fix

`jquery.datatables` will manipulate DOMs, sometimes remove them. In case
of component being reloaded with updated props, React will not be able
to find those removed nodes, causing a `cannot removeChild` error.

Because of the the way to assign row keys, if table shape changes (add
or remove columns), React may also have difficulty match the cached
nodes via keys.

In general it's a bad idea to directly manipulate React rendered DOM
nodes, so we better just let `jquery.datatables` handle everything.

In the future, once we removed `jquery.datatables`, a pure React
component will not have such issues.
@ktmud ktmud requested a review from kristw March 7, 2020 03:38
@ktmud ktmud requested a review from a team as a code owner March 7, 2020 03:38
@netlify
Copy link

netlify bot commented Mar 7, 2020

Deploy preview for superset-ui-plugins ready!

Built with commit b7596d0

https://deploy-preview-392--superset-ui-plugins.netlify.com

@kristw
Copy link
Collaborator

kristw commented Mar 7, 2020

Can't wait to get rid of jquery.datatable. sigh
Will this change remove the performance gain we had earlier?

@ktmud
Copy link
Contributor Author

ktmud commented Mar 7, 2020

Will this change remove the performance gain we had earlier?

I don't think so. jquery.datatables will still read an already constructed DOM tree. It's just an extra set innerHTML before the React component is mounted.

@codecov
Copy link

codecov bot commented Mar 7, 2020

Codecov Report

Merging #392 into master will increase coverage by 1.3%.
The diff coverage is 81.81%.

Impacted file tree graph

@@           Coverage Diff            @@
##           master    #392     +/-   ##
========================================
+ Coverage    1.48%   2.78%   +1.3%     
========================================
  Files         185     186      +1     
  Lines        5805    5812      +7     
  Branches      370     372      +2     
========================================
+ Hits           86     162     +76     
+ Misses       5707    5623     -84     
- Partials       12      27     +15
Impacted Files Coverage Δ
...rset-ui-legacy-plugin-chart-table/test/testData.ts 100% <100%> (ø)
...ui-legacy-plugin-chart-table/src/transformProps.ts 76.47% <66.66%> (+76.47%) ⬆️
...i-legacy-plugin-chart-table/src/ReactDataTable.tsx 75.64% <80%> (+75.64%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 073341b...b7596d0. Read the comment docs.

scripts/build.js Outdated Show resolved Hide resolved
import { mount } from 'enzyme';
import ReactDataTable from '../src/ReactDataTable';
import transformProps from '../src/transformProps';
import * as testData from './test_data';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps use specific import to enable warning if we later do not use some of these.
import { basic, advance } from ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wanted to have a namespace so it's more explicit in later code, but also wanted to keep variable names simple.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a default export for testData. I think it looks better than import *.

In the future, maybe all plugins can reuse the same test data---similar to switching visualization type in Superset.

Not seeing the console.warn errors anymore. So cleaning it up.

Previously it was from `<SuperChart />` component, but since we have
updated the test case to not use <SuperChart>, we are good now.
@kristw kristw merged commit 80384bc into apache-superset:master Mar 9, 2020
@ktmud ktmud deleted the react-legacy-table branch March 9, 2020 20:59
ktmud added a commit to ktmud/superset that referenced this pull request Mar 10, 2020
kristw pushed a commit to apache/superset that referenced this pull request Mar 10, 2020
nytai pushed a commit to preset-io/superset-ui-plugins that referenced this pull request Apr 27, 2020
* fix(legacy-table): avoid React DOM

`jquery.datatables` will manipulate DOMs, sometimes remove them. In case
of component being reloaded with updated props, React will not be able
to find those removed nodes, causing a `cannot removeChild` error.

Because of the the way to assign row keys, if table shape changes (add
or remove columns), React may also have difficulty match the cached
nodes via keys.

In general it's a bad idea to directly manipulate React rendered DOM
nodes, so we better just let `jquery.datatables` handle everything.

In the future, once we removed `jquery.datatables`, a pure React
component will not have such issues.

* fix(legacy-table): handle the case when percentMetrics is null

* fix(legacy-table): linting errors

* refactor: use nimbus build

* test(legacy-table): add React component tests

* test(legacy-table): more sophisticated cases

* fix: address PR apache-superset#392 comments

* chore(legacy-table): clean up tests case setups

Not seeing the console.warn errors anymore. So cleaning it up.

Previously it was from `<SuperChart />` component, but since we have
updated the test case to not use <SuperChart>, we are good now.

* fix(legacy-table): misleading comment
lexisstv pushed a commit to utrace-ltd/superset-ui-plugins that referenced this pull request Jun 1, 2020
* fix(legacy-table): avoid React DOM

`jquery.datatables` will manipulate DOMs, sometimes remove them. In case
of component being reloaded with updated props, React will not be able
to find those removed nodes, causing a `cannot removeChild` error.

Because of the the way to assign row keys, if table shape changes (add
or remove columns), React may also have difficulty match the cached
nodes via keys.

In general it's a bad idea to directly manipulate React rendered DOM
nodes, so we better just let `jquery.datatables` handle everything.

In the future, once we removed `jquery.datatables`, a pure React
component will not have such issues.

* fix(legacy-table): handle the case when percentMetrics is null

* fix(legacy-table): linting errors

* refactor: use nimbus build

* test(legacy-table): add React component tests

* test(legacy-table): more sophisticated cases

* fix: address PR apache-superset#392 comments

* chore(legacy-table): clean up tests case setups

Not seeing the console.warn errors anymore. So cleaning it up.

Previously it was from `<SuperChart />` component, but since we have
updated the test case to not use <SuperChart>, we are good now.

* fix(legacy-table): misleading comment
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants