Design and Implement a Table Component based on React.js - Part 1

Allen Fang
ShopBack Tech Blog
4 min readDec 25, 2018

--

I’m creator of react-bootstrap-table and react-bootstrap-table2. That is about three years journey for creating this two React UI library. Currently, I already deprecated react-bootstrap-table due to bad maintainability. It was published at three years ago when I was a Big Data Engineer, I made so many mistakes due to poor knowledges for React, Javascript and Frontend etc. That’s why I decided to create a new react-bootstrap-table2 since from the end of 2017.

This is a series posts and I will divide it as four parts.

  • Part1 - Big picture and design thought for a React table component
  • Part2 - Internal Design and Implementation
  • Part3 - React Component Customizability
  • Part4 - Monorepo Sharing

In this post, I would like to share some concepts and high level thought about what kind of table features we should provide to developer or user.

Rich Functional Table

If the table component you develop is just for internal use, I think probably you don’t need to think too much. However, if you want to open source, you are better to consider more rich functions. I’m jqGrid big fans cause of jqGrid support a lots of fantastic features as well as good flexibility for customization on each part of table.

In react-bootstrap-table we have a lots of cool features like: row selection, Excel-like keyboard navigation, row expand, pagination, cell edit, filter/search etc. These are key things for developer they may consider to use your library because you give them awesome built-in functionalities.

If you support a lots awesome feature, storybook is best choice to perform your feature online. Like react-bootstrap-table, we have a online demo built by storybook

Developer Friendly Library

Firstly, easier for developer to use your UI library is most important thing when you design whatever component or API. In React perspective, I got three principles:

Custom Data Management

It’s an important perspective when you design a table component based on React. In react-bootstrap-table we have a lots of features which involved data management, like column filter, table search, sort, pagination, cell editing etc. Most of cases, developer expect you to help them complete these stuffs but sometime is not. For example, they may want to perform their search logic or implement their pagination logic through server side.

In react-bootstrap-table I call it remote mode. Developer can enable remote mode either on all functionalities or specific function. Following is a real case :

const RemoteSort = props => (
<BootstrapTable
...
remote={ { sort: true } } // only enable remote for sort
onTableChange={ props.onTableChange }
/>
);
class Example extends React.Component {
state = { data: products }
handleTableChange = (type, { sortField, sortOrder, data }) => {
// perform you sorting logic here
const result = doMySort();
this.setState(() => ({ data: result}));
}
render() {
return (
<RemoteSort
data={ this.state.data }
onTableChange={ this.handleTableChange }
/>
);
}
}

The key point here is you are not only support custom data management but also allow developer to specify which part of data management they want to customize.

Controlled and Uncontrolled Management

This idea is almost same as above. I would like to use a dropdown component as an example:

That’s said I want to open source a dropdown react component, did you think following example a good idea to force user to use your component like that?!

import MyDropDown from 'my-dropdown';  // My open source componentclass Example extends React.component {
state = { currentOption: null }
handleOptionChange = (newOption) => {
this.setState(() => ({ currentOption: newOption }));
}
render() {
return (
<MyDropDown
options={ ... }
currentValue={ this.state.currentOption }
onChange={ this.handleOptionChange }
/>
)
}
}

Absolutely No. The only benefit for you is MyDropDown component is a stateless(pure) component, but the drawback is bad usage for your user, because they have to handle the dropdown state by themself. In this case, MyDropDown is just an Uncontrolled Component.

However, developer hope you can help them to handle the logic of dropdown change internally:

const Example = () => <MyDropDown options={...} />;

It’s simple apparently for developer, the dropdown component is self controlled which is a Controlled Component. Becasue developer is not necessary to handle the option changes in their code, if they need to know the current select value, you can consider to provide following ways for them:

  • Use a callback, like onChange and pass the newest value as argument.
  • Use React Refs.

In my opinion, if you want to open source a React component, you have to implement your component as Controlled and Uncontrolled both!!

Here is an example about how react-bootstrap-table support developer an Uncontrolled way to manage the row selection externally.

Exposed API

This is useful for developer when they want to:

  • Get internal state programmatically
  • Set or Control internal state programmatically

For example, in react-bootstrap-table we have column filter, but sometime developer want to do the filter programmatically or trigger the filter from their component or something. In addition, they may want to know what filter value is applied on which column. Hence, react-bootstrap-table give developer some way to access internal state or function.

For the developer, they can easy to do it like:

this.table.filter(...); // Call a filter function to do the filter
this.table.state.data; // Access the table state
<BootstrapTable ref={ n => this.table = n } ... />

When you are designing the react component, it’s better to think more about how developer they access your state or function. Design the function or state more flexible is good for exposed API definitely.

Conclusion

In this post, just share few high level thought when you design a table component. Actually, you can adopt these ideas to any React component as well. In the part 2, I will share more detail about How I design and implement a React table component.

--

--