Table component that supports both virtualized  table and tree tables
Tags: react, table, virtualized, opensource
Published: 2019-11-21 03:26:33

There is such a need, a React Suite (hereinafter referred to as [rsuite](https://github.com/rsuite/rsuite)) users, he needs a Table component to support tree data like Jira Portfolio, and need to support big data rendering. As of now (November 21, 2019), no supportable components have been found in the open source UI library, so rsuite supports this feature in the latest release.

Next, let’s see how these two features are supported in [rsuite](https://github.com/rsuite/rsuite)?

### Large table virtualization

First, let’s look at supporting big data rendering. Rendering too many DOM elements in a page can cause performance problems. There must be a solution to optimize it. Let’s call it big table virtualization for the time being.
The so-called large form virtualization is to set a large data (such as 10000 data) for the table, and then virtual one table to hide the data that does not need to be displayed.

In order to solve the performance problems that occur when a large number of DOMs are rendered by the browser, we can’t render 10,000 pieces of data to the page, in one way, only render the data in the visible range. At the same time, a scroll bar is set for the table, and the data of the area is only rendered when scrolling to the area to be displayed, and the number of DOMs is reduced.

![image](https://miro.medium.com/max/900/1*fm7F7OLKf148_T5mCtQ1lw.png)

[Preview](https://rsuitejs.com/en/components/table)

The above is a Table of 10000 data. The rendered HTML structure is:
![image](https://miro.medium.com/max/1131/1*C1snohlYb60xVmx278BRRg.png)

We can see that only 14 `rs-table-row` are rendered in the Table , the first and last ones are not `children`, just a placeholder with height. Every `rs-table-row` is absolutely positioned, so even if you delete a Row in a Table, or add a Row, it will not change the position of other Rows. On this basis, by obtaining the scroll position of the scroll bar, it is easy to judge whether the top value of the current Row is within the visible range of the Table, and update all the Rows at the same time.
Many excellent libraries implement such a function, and the principle is basically the same. For example, `react-virtualized` provides the Table component, but he does not support Tree.

### Tree Table

The need to display tree data in a table, we see more like the Gantt chart table. It has a child-parent relationship and can expand child nodes.

![tree-table](https://miro.medium.com/max/610/1*Lw0hHFkCKnUvnl6nbCES_A.png)

Such a table is supported by many Table components, but it is relatively cumbersome if you need to support virtualization at the same time, because you need to recalculate the displayed DOM and set the position of the scroll bar when you expand the closed node.

![image](https://miro.medium.com/max/781/1*vREXGq38IrZlwjVB_-Uvbw.png)

In versions prior to the [rsuite](https://github.com/rsuite/rsuite) Table component, the DOM structure of the rendered tree table was a Tree. So first you need to flatten the Tree, convert a one-dimensional array, set the parent node for each node, and render the relative position of the Tree node by the depth of the parent node. Then it is better to deal with, just need to deal with the data filtering when clicking the expand and close node button.

### Install and use

The design of rsuite’s Table component is very convenient for development. The structure is defined by the `<Table>`, `<Column>`, `<Cell>`, `<HeaderCell>` components, and the table data is rendered by assigning the data property.

Install

```
npm install rsuite --save
```

> If you only want to use Table in your project and don’t want to install the entire [rsuite]([rsuite](https://github.com/rsuite/rsuite)) library, you can install [rsuite-table](https://github.com/rsuite/rsuite-table) separately.

Example:

```jsx
import { Table } from 'rsuite';

const { Column, HeaderCell, Cell } = Table;
const data = [{ id: 1, name: 'foobar', email: 'foobar@xxx.com' }];

ReactDOM.render(
  <Table height={400} data={data}>
    <Column width={70}>
      <HeaderCell>ID</HeaderCell>
      <Cell dataKey="id" />
    </Column>
    <Column width={200}>
      <HeaderCell>Name</HeaderCell>
      <Cell dataKey="name" />
    </Column>
    <Column width={200}>
      <HeaderCell>Email</HeaderCell>
      <Cell dataKey="email" />
    </Column>
  </Table>
);
```

### Finally

As a mature Table component, what features does it support?

- Resizable column width
- Fixed column
- Sort
- Pagination
- Editable
- Merge Cells
- Custom cell
- Automatic column width
- Expandable row

The only question left is whether you are willing to use it in your project?

https://github.com/rsuite/rsuite