Skip to main content Skip to footer

Building a Smart Data Table in React

Tables are one of the easiest ways to present data on web pages. Plain HTML tables can meet the basic data presentation needs, but trying to squeeze anything sophisticated from them will quickly make you frustrated.

This is when you need to make some important decisions about your application development path. You can start coding enhancements around old-fashioned HTML tables — at the risk of losing focus on your project — or you look at the existing products that are designed to solve your problems.

Today’s market offers dedicated smart table controls that handle the table part for you and provide additional features, including selection modes, sorting, and column reordering.

Many companies use data tables to show complex reports, dashboards, financial data, sales results, and even interactive spreadsheets. High demand begot specialized supply, so tables are well represented in web component libraries.

In this article, we'll discuss which capabilities are expected from a smart table, assess a few open-source alternatives, and demonstrate how to create superior HTML smart data tables with our solution for the React JavaScript library. We are assuming that you have some web development experience and preferably familiarity with React.

To see the finished code sample, you can find it running here on StackBlitz.

Ready to Get Started? Download Wijmo Today!

Table Capabilities

There are some key features that people expect from a smart data table.

  • Data features:

    • Load data from various sources, including local files, databases, and APIs
    • Searching, filtering, and sorting options
    • Load and display of large datasets with pagination
    • Ability to import and export data
  • UI features:

    • Showing and hiding columns
    • Inline editing
    • Responsiveness — built-in support for multiple devices
    • Resizable columns to accommodate long data points inside a column (multi-line comments)
    • Horizontal and vertical scroll support
    • Data validations and visualizations, such as sparklines

Modern frameworks have built-in implementations of some of these features. However, you have to code more advanced features yourself.

Open Source Frameworks

Created and maintained by Facebook, React is a massively popular open-source JavaScript library. Currently, it holds around 60% of the JavaScript framework market share. With such widespread adoption in the industry, it’s no wonder that many products have been created to serve applications built on React.

Here are some popular open-source smart data table libraries made for React:

These open-source projects have advantages and disadvantages. Depending on which feature you are looking for, some of these components are better than others.

Create a React App with React Data Grid

Let’s build a new Node-based, React application with React Data Grid, an open-source component that has a look-and-feel close to what we are trying to demonstrate.

Install Node.js. Then, using a command-line console, create a new Node React app:

npx create-react-app my-app  
cd my-app  
npm start

Install the React Data Grid package. Open the package.json file and add these lines in the dependencies section:

"babel-loader": "^8.1.0",  
"react-data-grid": "5.0.1",  
"react-data-grid-addons": "5.0.4",  
"bootstrap": "^4.5.2"

append the following lines after the browserslist section:

"devDependencies": {  
  "immutable": "^4.0.0-rc.12"  
}

To install the React Data Grid package and its dependencies, run the npm install command-line instruction:

npm install

Add a new data folder under the src folder, and create a new file named data.js. The user will use the data to populate our data grid:

export const recentSales = [  
  {  
    id: 1,  
    country: "Canada",  
    soldBy: "Bill",  
    client: "Cerberus Corp.",  
    description: "Prothean artifacts",  
    value: 6250,  
    itemCount: 50  
  },  
  {  
    id: 2,  
    country: "Canada",  
    soldBy: "Bill",  
    client: "Strickland Propane",  
    description: "Propane and propane accessories",  
    value: 2265,  
    itemCount: 20  
  },  
  {  
    id: 3,  
    country: "USA",  
    soldBy: "Ted",  
    client: "Dunder Mifflin",  
    description: "Assorted paper-making supplies",  
    value: 4700,  
    itemCount: 10  
  },  
  {  
    id: 4,  
    country: "USA",  
    soldBy: "Ted",  
    client: "Utopia Planitia Shipyards",  
    description: "Dilithium, duranium, assorted shipbuilding supplies",  
    value: 21750,  
    itemCount: 250  
  },  
  {  
    id: 5,  
    country: "USA",  
    soldBy: "Ted",  
    client: "Glengarry Estates",  
    description: "Desks, phones, coffee, steak knives, and one Cadillac",  
    value: 5000,  
    itemCount: 5  
  },  
  {  
    id: 6,  
    country: "Germany",  
    soldBy: "Angela",  
    client: "Wayne Enterprises",  
    description: "Suit armor and run-flat tires",  
    value: 35000,  
    itemCount: 25  
  },  
  {  
    id: 7,  
    country: "Germany",  
    soldBy: "Angela",  
    client: "Stark Industries",  
    description: "Armor and rocket fuel",  
    value: 25000,  
    itemCount: 10  
  },  
  {  
    id: 8,  
    country: "Germany",  
    soldBy: "Angela",  
    client: "Nakatomi Trading Corp.",  
    description: "Fire extinguishers and replacement windows",  
    value: 15000,  
    itemCount: 50  
  },  
  {  
    id: 9,  
    country: "UK",  
    soldBy: "Jill",  
    client: "Spaceley Sprockets",  
    description: "Anti-gravity propulsion units",  
    value: 25250,  
    itemCount: 50  
  },  
  {  
    id: 10,  
    country: "UK",  
    soldBy: "Jill",  
    client: "General Products",  
    description: "Ion engines",  
    value: 33200,  
    itemCount: 40  
  }  
];

Add a new components folder under the src folder, and create a new file named OpenSourceTable-Demo.js:

/my-app  
  /src  
    /components  
      OpenSourceTable-Demo.js

Open the OpenSourceTable-Demo.js file and add the following code. (Here, we import the ReactDataGrid component and declare the React state variables that will be used by the data grid as column definitions and the component’s data source):

import 'bootstrap/dist/css/bootstrap.min.css';  
import React, { useState } from 'react';  
import ReactDOM from "react-dom";  
import ReactDataGrid from "react-data-grid";  
import { recentSales } from "../data/data";

export const OpenSourceTableDemo = () => {

  const [columns, setColumns] = new useState([  
    { key: "id", name: "Id" },  
    { key: "country", name: "Country" },  
    { key: "soldBy", name: "Sold by" },  
    { key: "client", name: "Client" },  
    { key: "description", name: "Description" },  
    { key: "value", name: "Value" },  
    { key: "itemCount", name: "Item Count" }  
  ]);

  const [sales, setSales] = new useState(recentSales);  
}

Modify the OpenSourceTableDemo component so that it returns the HTML with the ReactDataGrid component:

return (  
  <div className="card main-panel">  
    <div className="card-header">  
      <h1>Open Source</h1>  
    </div>  
    <div className="card-body">  
    <h5>React Data Grid Demo</h5>  
      <p>  
        Building a Smart Data Table in React with React Data Grid  
      </p>           
      <div className="container-fluid">  
        <div className="row">  
            <ReactDataGrid  
                columns={columns}  
                rowGetter={i => sales[i]}  
                rowsCount={recentSales.length}  
              />  
        </div>  
      </div>  
    </div>  
  </div>);

Edit the App.js file and replace its contents with the lines below:

import React from 'react';  
import './App.css';  
import { OpenSourceTableDemo } from './components/OpenSourceTable-Demo.js'

function App() {  
  return (  
    <OpenSourceTableDemo/>  
  );  
}

export default App;

Now run the app:

npm start

Once the app is running, you’ll see the React Data Grid displaying the sales data:

Smart Data Table React

To show some of the component features, let’s start customizing our open-source data grid to support cell value updates, row sorting, and column reordering.

Implement Cell Value Update

Open the OpenSourceTable-Demo.js file and add the editable: true attribute to each of the grid column definitions:

{ key: "id", name: "Id", editable: true },  
{ key: "country", name: "Country", editable: true },  
{ key: "soldBy", name: "Sold by", editable: true },  
{ key: "client", name: "Client", editable: true },  
{ key: "description", name: "Description", editable: true },  
{ key: "value", name: "Value", editable: true },  
{ key: "itemCount", name: "Item Count", editable: true }

Add a new onGridRowsUpdated function to handle cell updates and update the underlying data source:

  const onGridRowsUpdated = ({ fromRow, toRow, updated }) => {  
    const s = sales.slice();  
    for (let i = fromRow; i <= toRow; i++) {  
      s[i] = { ...s[i], ...updated };  
    }  
    setSales(s);  
  };

Modify the ReactDataGrid component to add the enableCellSelect={true} attribute and an onGridRowsUpdated={onGridRowsUpdated} event handler:

<ReactDataGrid  
  columns={columns}  
  rowGetter={i => sales[i]}  
  rowsCount={recentSales.length}  
  enableCellSelect={true}  
  onGridRowsUpdated={onGridRowsUpdated}  
/>

These changes allow your React Data Grid to handle updates and persist them in the underlying data source:

Smart Data Table React

Implement Row Sorting

Open the OpenSourceTable-Demo.js file and add the sortable: true attribute to each column definition to enable column sortability:

{ key: "id", name: "Id", editable: true, sortable: true },  
{ key: "country", name: "Country", editable: true, sortable: true },  
{ key: "soldBy", name: "Sold by", editable: true, sortable: true },  
{ key: "client", name: "Client", editable: true, sortable: true },  
{ key: "description", name: "Description", editable: true, sortable: true },  
{ key: "value", name: "Value", editable: true, sortable: true },  
{ key: "itemCount", name: "Item Count", editable: true, sortable: true }

Implement the new sortRows function:

  const sortRows = (initialRows, sortColumn, sortDirection) => rows => {  
    const comparer = (a, b) => {  
      if (sortDirection === "ASC") {  
        return a[sortColumn] > b[sortColumn] ? 1 : -1;  
      } else if (sortDirection === "DESC") {  
        return a[sortColumn] < b[sortColumn] ? 1 : -1;  
      }  
    };  
    return sortDirection === "NONE" ? initialRows : [...rows].sort(comparer);  
  };

Modify the ReactDataGrid component to implement the onGridSort event handler and reference the function we have just created:

<ReactDataGrid  
  columns={columns}  
  rowGetter={i => sales[i]}  
  rowsCount={recentSales.length}  
  enableCellSelect={true}  
  onGridRowsUpdated={onGridRowsUpdated}  
  onGridSort={(sortColumn, sortDirection) =>  
      setSales(sortRows(sales, sortColumn, sortDirection))  
  }  
/>

Go back to the web page and notice how the columns are now sortable:

Smart Data Table React

Implement Column Reordering

Open the OpenSourceTable-Demo.js file and add this declaration after the imports section:

const {  
  DraggableHeader: { DraggableContainer }  
} = require("react-data-grid-addons");

Add the draggable: true property to each column definition to enable column repositioning:

{ key: "id", name: "Id", editable: true, sortable: true, draggable: true },  
{ key: "country", name: "Country", editable: true, sortable: true, draggable: true },  
{ key: "soldBy", name: "Sold by", editable: true, sortable: true, draggable: true },  
{ key: "client", name: "Client", editable: true, sortable: true, draggable: true },  
{ key: "description", name: "Description", editable: true, sortable: true, draggable: true },  
{ key: "value", name: "Value", editable: true, sortable: true, draggable: true },  
{ key: "itemCount", name: "Item Count", editable: true, sortable: true, draggable: true }

Add the onHeaderDrop function to handle column drag-and-drop event:

const onHeaderDrop = (source, target) => {  
  var columnsCopy = columns.slice();  
  const columnSourceIndex = columns.findIndex(  
    i => i.key === source  
  );  
  const columnTargetIndex = columns.findIndex(  
    i => i.key === target  
  );

  columnsCopy.splice(  
    columnTargetIndex,  
    0,  
    columnsCopy.splice(columnSourceIndex, 1)[0]  
  );

  setColumns(columnsCopy.splice());  
  setColumns(columnsCopy);  
};

Wrap your existing ReactDataGrid component inside a new DraggableContainer component:

  <DraggableContainer onHeaderDrop={onHeaderDrop}>  
      <ReactDataGrid  
            columns={columns}  
            rowGetter={i => sales[i]}  
            rowsCount={recentSales.length}  
            enableCellSelect={true}  
            onGridRowsUpdated={onGridRowsUpdated}  
            onGridSort={(sortColumn, sortDirection) =>  
              setSales(sortRows(sales, sortColumn, sortDirection))  
            }  
        />  
  </DraggableContainer>

Rerun the app and try moving the grid columns around:

Smart Data Table React

That looks pretty good, but it was a lot of work to implement those features. Now you're on the hook to maintain that code.

Effective Alternatives

If your company develops first-rate, enterprise-grade applications, you should look into more professional products that offer support for multiple JavaScript frameworks and cover a complete functionality range.

We provide several data table products that can be implemented in a React app with a few code lines. These products are packed with a rich set of ready-to-use features that require no customization, unlike the open-source components we’ve discussed above.

Let’s have a look at several lightweight, smart table products provided, including SpreadJS, DataViewJS, and Wijmo FlexGrid.

SpreadJS

SpreadJS is the World's #1 selling JavaScript Spreadsheet with over 450 Excel functions. Using SpreadJS, you can quickly deliver Excel-like spreadsheet experiences with zero dependencies on Excel, with full support for React, Vue, Angular, and TypeScript.

SpreadJS enables you to create financial reports and dashboards, budgeting and forecasting models, scientific, engineering, healthcare, education, science lab notebooks, and other JavaScript applications for standard spreadsheet scenarios.

For more advanced spreadsheet use cases, SpreadJS allows you to create custom spreadsheets, advanced grids, dashboards, reports, and data input forms with the comprehensive API. Powered by a high-speed calculation engine, SpreadJS enables the most complex calculations.

SpreadJS supports integration by importing and exporting features that work seamlessly with the most demanding Excel.xlsx spreadsheets.

DataViewJS

DataViewJS is a DataGrid platform focused on advanced data presentation. It goes beyond the traditional tabular displays by providing several presentation views, including tree, card, masonry, trellis, timeline, Gantt, calendar, and grid.

With a single line of code, DataViewJS' customization allows you to change layouts freely. It fully supports Angular, React, and Vue.JS.

Wijmo FlexGrid

FlexGrid is one of the Wijmo product family, which also includes JavaScript/HTML5 UI Components such as FlexChart, Input, PivotChart, FinancialChart, ReportViewer, and so on. Wijmo's JavaScript DataGrid fully supports Angular, AngularJS, ReactJS, VueJS, and Knockout.

The lightning speed, extensibility, and independence make Wijmo FlexGrid the ultimate JavaScript smart data grid. FlexGrid’s small footprint improves performance and reduces load time by keeping your web applications compact.

You can take advantage of Excel-like features of FlexGrid, such as data aggregation, cell merging, star sizing, and cell freezing. Also, Cell Templates provide limitless templates with support for declarative markup and binding expressions.

All these products are lightweight and work with virtualization, meaning they keep running at high performance even when they are connected to massive data sources.

Implement a Smart Data Table

Let’s see how to implement a Wijmo React DataGrid smart data table in the Node app we’ve built previously.

Install the Wijmo package with npm:

npm install @grapecity/wijmo.react.all

In the components folder under the src folder, create a new file named WijmoFlexGrid-Demo.js:

/my-app  
  /src  
    /components  
      WijmoFlexGrid-Demo.js

Open the WijmoFlexGrid-Demo.js file and add the following code. (Here, we import the WijmoFlexGridDemo component and declare the React state variable that will be used by the FlexGrid as the component’s data source):

import '@grapecity/wijmo.styles/wijmo.css';  
import 'bootstrap/dist/css/bootstrap.css';  
import '@grapecity/wijmo.react.grid';  
import React, { useState } from 'react';  
import { FlexGrid, FlexGridColumn } from '@grapecity/wijmo.react.grid';  
import { recentSales } from "../data/data";

export const WijmoFlexGridDemo = () => {

  const [sales, setSales] = new useState(recentSales);

    }

Modify the WijmoFlexGridDemo component so that it returns the HTML with the FlexGrid component:

return (  
    <div className="card main-panel">  
      <div className="card-header">  
          <h1>GrapeCity</h1>  
      </div>  
      <div className="card-body">  
      <h5>Wijmo FlexGrid Demo</h5>  
        <p>  
          Building a Smart Data Table in React  
        </p>           
        <div className="container-fluid">  
          <div className="row">  
            <FlexGrid itemsSource={sales}>  
              <FlexGridColumn width={50} binding='id' header="ID" />  
              <FlexGridColumn width={200} binding='client' header="Client" />  
              <FlexGridColumn width={320} binding='description' header="Description" />  
              <FlexGridColumn width={100} binding='value' header="Value"/>  
              <FlexGridColumn width={100} binding='itemCount' header="Quantity" />  
              <FlexGridColumn width={100} binding='soldBy' header="Sold By" />  
              <FlexGridColumn width={100} binding='country' header="Country" />  
            </FlexGrid>  
          </div>  
        </div>

      </div>  
    </div>);

Edit the App.js file to include the reference to our new WijmoFlexGridDemo component:

import React from 'react';  
import './App.css';  
import { OpenSourceTableDemo } from './components/OpenSourceTable-Demo.js'  
import { WijmoFlexGridDemo } from './components/WijmoFlexGrid-Demo.js'

function App() {  
  return (  
    // <OpenSourceTableDemo/>  
    <WijmoFlexGridDemo/>  
  );  
}

export default App;

Run the app:

npm start

Once the app is running, you’ll see the FlexGrid displaying the sales data:

Smart Data Table React

Cell editing is an out-of-the-box feature in FlexGrid. You can double-click the cells and start editing in place:

Smart Data Table React

By default, a FlexGridColumn is editable. But you can disable editing by explicitly defining the isReadOnly property in the FlexGridColumn component:

<FlexGridColumn width={50} binding='id' header="ID" isReadOnly='true' />

Also, by default, every FlexGrid column is sortable in ascending or descending order.

Smart Data Table React

You can lock column sorting by setting the allowSorting property to “false”:

<FlexGridColumn width={200} binding='client' header="Client" allowSorting={false}/>

FlexGrid comes with the ability to reposition columns out of the box freely:

Smart Data Table React

You can disable column reordering by setting the FlexGridColumn’s allowDragging property to “false”:

<FlexGridColumn width={200} binding='client' header="Client" allowDragging={false}/>

So, all the customizations we need to implement on the open-source React Data Grid control are built-in here.

Import Excel Data

Let’s see how we can import Excel data into our FlexGrid component.

Append the following HTML segment after the card-body div in the return() function:

<div className="card-body">  
  <div className="card-footer">     
      <div className="input-group">  
        <div className="custom-file">  
            <input type="file" id="importFile"/>  
        </div>  
        <div className="input-group-prepend">  
            <input type="button" value="Import"/>  
        </div>  
      </div>  
  </div>

Run the application and notice the import section at the bottom of the page:

Smart Data Table React

Tell the Import button to import the file into our FlexGrid component. Add the onClick function to the input element and pass the name of the function as “import”:

<input type="button" onClick={load} value="Import"/>

Add a new load function inside the component class. Here, we’ll first obtain the full path of the user selected file:

  var load = () => {  
    let fileInput = document.getElementById("importFile");  
    if (fileInput.files[0]) {

    }  
  }

At this point, we’ll need a reference to the FlexGrid instance. Go back to the component declaration and add an event handler that is triggered when the FlexGrid is initialized:

<FlexGrid itemsSource={sales} initialized={initializeFlexGrid}>

Add a declaration for the flexgrid variable and a new function to set it up on the FlexGrid initialization:

  const [flexGrid, setFlexGrid] = useState({});  

  var initializeFlexGrid = (flexGrid) => {  
      setFlexGrid(flexGrid);  
  }

Add an import directive to the Wijmo library that handles Excel file contents:

import * as wjcGridXlsx from "@grapecity/wijmo.grid.xlsx";

Back to the load function, add a call to the loadAsync function of the Wijmo library to load the file’s contents into the FlexGrid:

  var load = () => {  
    let fileInput = document.getElementById("importFile");  
    if (fileInput.files[0]) {  
      wjcGridXlsx.FlexGridXlsxConverter.loadAsync(flexGrid, fileInput.files[0], { includeColumnHeaders: true }, function (workbook) {  
        flexGrid.autoSizeColumns();  
     });  
    }  
  }

The Wijmo.xlsx library depends on a JavaScript zip library to compress files. Let’s install this dependency by running this console command:

npm install jszip --save

Rerun the app and test the import feature.

npm start

Open Excel and create a new Demo.xlsx file with these contents:

Smart Data Table React

Back in our React app, click Choose File, select the Demo.xlsx location, and click the Import button to see the result:

Smart Data Table React

Finally, let’s see what’s needed to export data from our FlexGrid to Excel.

Replace the Import button markup with the following HTML snippet to add the new Export button:

<div className="input-group-prepend">
  <div className="btn-group">
    <input type="button" onClick={load} value="Import" />
    <input
      type="button"
      onClick={save}
      className="input-group-text"
      value="Export"
    />
  </div>
</div>;

Note that the onClick event handler is pointing to the save function. Let’s implement this function inside the component class:

  var save = () => {

  }

To export FlexGrid data to an .xlsx file, we need to call the saveAsync function of the FlexGridXlsxConverter class:

  var save = () => {  
    wjcGridXlsx.FlexGridXlsxConverter.saveAsync(flexGrid, {  
        includeColumnHeaders: true,  
        includeCellStyles: false,  
        formatItem: false  
    }, "FlexGrid.xlsx");  
  }

Run the app once again and test the Export button:

Smart Data Table React

Now you can open the .xlsx file exported by the FlexGrid component:

Smart Data Table React

The above demo barely scratches the surface of the FlexGrid component. We recommend that you explore the Wijmo family of JavaScript UI Components and Tools page for complete documentation, demos, and examples written for Angular, React, and Vue.

If you want to see the finished code sample, you can find it running here on StackBlitz.

Wrapping Up

You can create and use React-based smart data tables in various ways. Some approaches require far more manual work than others, but you can’t tell that until you have already spent enough time trying to use them.

There are plenty of free and open-source table libraries that might meet your everyday needs. We’ve seen how to implement one of them in this article.

However, when it comes to business and enterprise projects, you, as a developer, don’t want to be distracted and waste your time developing workarounds, additional features, or configuration. This is why a commercial library component suite like Wijmo ensures a solid return on investment.

Built to be framework-agnostic, the Wijmo JavaScript library includes full support for Angular, AngularJS, ReactJS, and VueJS, with the same grid across frameworks. For your organization, this means freedom of choice and the ability to save time and development effort if you decide to migrate to another JavaScript framework.

Ready to Get Started with Wijmo? Download a 30 Day Free Trial Today!


comments powered by Disqus