Since its release, React has risen to one of the most prominent front-end web frameworks available. While React has gained prominence over the last several years, datagrids have been one of the most common visual software elements since the advent of UIs.

The popularity of React and the commodity of datagrids means that there are a plethora of options to choose from when building your application. But among open-source, commercial, and homegrown datagrids, one solution stands above the rest: Wijmo’s FlexGrid.

In a previous post, we discussed the usefulness and importance of datagrids and why FlexGrid is the best Angular datagrid on the market. We will now dive into the benefits of using FlexGrid in React and demonstrate why FlexGrid is the best datagrid solution for your React applications.

In this article, I’ll talk about:

  • Why datagrids are useful as UI elements
  • How FlexGrid rises above all other datagrid components
  • Examples of how simple it is to use FlexGrid in a React web application

Try Wijmo's controls

Download the latest version of Wijmo

Download Now!

FlexGrid**, included in GrapeCity's Wijmo JavaScript UI library, is the best plug-and-play datagrid for React.

flexgrid

Why Datagrids?

Even if you’re not a software developer, you’ve been exposed to the paradigm of datagrids. Grouping and sorting data aren’t merely for the meticulous–it’s human nature. Datagrids appeal to the instinct that drives us to organize take in, and understand as much data as possible, as efficiently as possible.

The usefulness and universality of datagrids have allowed them to pervade throughout time, but not without some amount of evolution. With the advent of screens in the digital age, the datagrid has changed more than ever before.

Now, grids are more useful than ever, not only for displaying data but also for editing it. Could you imagine creating a sales report or monthly budget using Microsoft Word? With automatic conveniences, such as sorting, filtering, and autocomplete, plus advanced features like custom formulas, Microsoft Excel would be the natural choice for most users.

Beyond the helpful and time-saving features, most users would naturally choose Excel because it's what they first experienced when it came to datagrids on a computer. Excel is familiar. Any good UX designer or business analyst will tell you: educating users is difficult and expensive. This is one of the greatest advantages of datagrids in general – they are intuitive.

Although Excel is the most common example of software using a datagrid, the paradigm has proliferated throughout the software world. As web apps continue to replace the traditional native applications that we’re used to, it only makes sense that datagrids would make their way to web app UIs as well. At GrapeCity, we’ve found that industries across the board are including datagrid UI components in new web app projects.

Whether you’re building an app to track manufacturing stats, analyze financial data, or create sales reports, I’m willing to bet you’ve already thought about the intuitiveness a datagrid would add. And, as we’ll see, Wijmo’s FlexGrid can maximize the bang for your buck by providing the best datagrid UX with the best performance available.

flexgrid

Datagrid components like FlexGrid provide natural, intuitive interfaces between humans and data.

Wijmo's FlexGrid: The Best Datagrid Component Solution

So, now we know that the biggest advantage of using datagrids is that they’re inherently intuitive. That’s a huge plus for the end-user experience, but what about the developers that are building the applications? Creating a datagrid UI component from scratch is certainly no small task for any development team. It’s quite possible that building a datagrid for your application is just as expensive as educating users about a different UI component that you create.

Fortunately, that’s where FlexGrid comes in! Just import Wijmo’s library into your application, add FlexGrid to your application, and attach it to your data source. With just a few simple steps, your application now includes a full-functioning datagrid! If the greatest advantage of using a datagrid is that it creates a better end-user experience, the benefit of using a third-party datagrid is that it creates a better developer experience.

As we continue through this article, I’ll use examples to show how Wijmo’s FlexGrid offers the biggest boost in efficiency to development workflow with out-of-the-box React interoperability. But first, let's look at what sets FlexGrid apart from the competition as a pluggable datagrid component.

The FlexGrid Package Performance: Extensibility and Familiarity with a Small Footprint

Creating React’s most powerful datagrid component didn’t happen overnight. In fact, FlexGrid is older than Wijmo itself. FlexGrid was first written in 1996 using C++ for Visual Basic. It even shipped as a part of Visual Studio! It has since evolved and has been refined in many platforms, the most recent being JavaScript.

Decades of user input and refinement have resulted in a high-performance datagrid with an extensively documented API. But, there’s a reason that FlexGrid has retained its name all this time; stressing our “Flex Philosophy” is a top priority for us.

Controls should include only the key set of features required and offer everything else through an extensibility model.

Features like sorting, grouping, editing, and filtering are built-in, while other bells and whistles are offered as easily implementable, optional extensions of FlexGrid. This keeps the controls small and fast and gives both our customers and us the ability to build unique custom features.

Performance

Many React developers choose the framework for its emphasis on out-of-the-box performance and lightweight nature. FlexGrid ensures that you won’t have to sacrifice either by focusing on maintaining speed and a small footprint.

The Wijmo development team keeps the footprint of FlexGrid small by requiring no external dependencies. As a matter of fact, the FlexGrid only adds about 25k (gzipped) to your application.

Like React’s handling of the component DOM, FlexGrid also virtualizes all its child elements. You can load millions of rows of data in a matter of seconds – all on the client. This is extremely important to React interoperability. FlexGrid is the most performant React datagrid because it works seamlessly with React’s highly optimized virtualization algorithm.

Familiarity

FlexGrid bases nearly all its interaction behavior on Excel, which – as stated previously – is probably the most common datagrid/datatable used by any end-user. People expect certain behaviors when scrolling, clicking and especially using key commands (including clipboard functions).

Instead of inventing our own behaviors, we mimic Excel, and end-users immediately feel comfortable using our datagrid. Surprisingly, many other datagrids either invent their own behavior or don’t fully support keyboard actions. For example, you may select a row in a grid and hold the down arrow key, and the grid may not function as expected.

Accessibility

We’re extremely excited that we can say that our FlexGrid control offers full accessibility support for all of the most popular modern web browsers. Making a control as dense and complex as a datagrid accessible is a conundrum at best, and no other datagrid components offer FlexGrid’s level of framework interoperability and accessibility.

If you’d like to check out the details of how FlexGrid makes your data accessible to everyone, check out our blog post about accessibility development. Whether you have a standalone accessibility team or not, you can ensure that your application complies with the latest standards by using FlexGrid.

FlexGrid and React: A Match made in Web Development Heaven

FlexGrid does much more than seamlessly integrate with React’s powerful, high-performance render engine. Our datagrid component makes it fun, easy, and natural to add datagrids to your web application UIs.

Now for the fun stuff! Let’s look at some specific examples that illustrate the advantages of FlexGrid’s React interoperability.

Datagrid Example: Get Up and Running with create-react-app

Wijmo ships with both CommonJS and ES modules for all its components, including FlexGrid! And since Wijmo is written with an interoperability layer for React, you can import FlexGrid like any other React class component.

All of this means that you can create a React project and add FlexGrid with just a few simple steps. Thanks to Facebook’s infinitely useful create-react-app project, you don’t even need to worry about bootstrapping or tooling setup.

To illustrate how easy it is to use FlexGrid, we’ll walk through the process of setting up a React app, including Wijmo in your application and rendering a grid full of data to the screen.

First, you’ll need to create your own React application. Run the following command at your project's designated location:

npx create-react-app flexgrid-app

This will set up our React application, named "flexgrid-app".

Next, we'll install Wijmo in our application. Since we're building a React application, we only need to include the React modules. This is done with the following command:

npm install @grapecity/wijmo.react.all

Congratulations! You now have complete access to Wijmo’s entire UI library, including FlexGrid and its API. You can even use it directly in JSX markup as well! We’ll go over how to do that next.

Declaring FlexGrid in JSX Markup

Continuing with the work that we’ve done above, we’re now going to see how we can render a FlexGrid now that we’ve imported the Wijmo code into the App component.

Before we get to writing any actual code, we'll need to import the component that we'll be using, as well as Wijmo's CSS file so that FlexGrid will display correctly:

import '@grapecity/wijmo.styles/wijmo.css';
import * as wjcGrid from '@grapecity/wijmo.react.grid';

There will be some default JSX markup inside of the App class’ render() function. Go ahead and delete that default JSX and replace it with the following:

<div>
  <wjcGrid.FlexGrid itemsSource={this.state.data} />
</div>

For a 3-line code snippet, a lot is going on here. Before I talk about what makes declaring components in markup so important, let’s finish the example. There’s still one thing that we’re missing to load up the FlexGrid properly.

You may have noticed that the itemsSource property references the App component’s state. Since there currently is no default state defined for App, FlexGrid will render with no data! To fix this, we're going to add some mock data to the datagrid. Add the following code within the App class component:

this.state = {
  data: [
    { id: Math.floor(Math.random() * 1000, customer: 'Gia Shields', sale: Math.random() * 100000 },
    { id: Math.floor(Math.random() * 1000, customer: 'Jayden Foster', sale: Math.random() * 100000 },
    { id: Math.floor(Math.random() * 1000, customer: 'Selena Casey', sale: Math.random() * 100000 },
  ]
};

Now go ahead and fire up your app by running npm start and behold FlexGrid in all its glory! Before moving on to exploring some of the more interesting features offered by FlexGrid in React, think about the implications of being able to declare a complex datagrid control in markup entirely.

If you can’t wait to see this app in action, check out the live sample on Stackblitz.

Declarative markup is ideal for following the MVVM (Model-View-ViewModel) design pattern, and we can fully configure our components within the view (markup). FlexGrid supports declaring its entire API using natural, unextended JSX markup. You can set properties, attach events, and even configure child components (like columns) entirely in markup.

You might have already guessed that there’s something special about FlexGrid’s itemsSource being connected to the component state. More on that soon...

Easily Bind FlexGrid API Events to Component Functions

Since it was so easy to attach FlexGrid properties to the component state, it follows that attaching FlexGrid events to handler functions should be just as easy, right? If that’s what you were thinking after reading the last section, then you’re correct! Just as data from the App component’s state can be passed to the FlexGrid via props, component functions can be passed as handlers for FlexGrid events.

To demonstrate, let’s add a new feature to our example. Since we already have a working FlexGrid with some data, we have access to dozens of events that the FlexGrid API supports out-of-the-box. We’ll take advantage of two of those events – beginningEdit and cellEditEnded – to display a descriptive message when a user starts editing a cell in the datagrid.

Before we move any further, however, double-check to make sure the code for your App component (in App.js) looks like this:

import React from 'react';
import ReactDom from 'react-dom';
import './styles.css';

import '@grapecity/wijmo.styles/wijmo.css';
import * as wjcGrid from '@grapecity/wijmo.react.grid';

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [
        { id: Math.floor(Math.random() * 1000, customer: 'Gia Shields', sale: Math.random() * 100000 },
        { id: Math.floor(Math.random() * 1000, customer: 'Jayden Foster', sale: Math.random() * 100000 },
        { id: Math.floor(Math.random() * 1000, customer: 'Selena Casey', sale: Math.random() * 100000 },
      ]
    };
  }

  render() {
    return (
      <div>
        <wjcGrid.FlexGrid itemsSource={this.state.data} />
      </div>
    );
  }
}

export default App;

Now that we’re on the same page, let’s continue and add our edit-tracking feature! First, we’ll need to add some new properties to the App component’s state to track whether a cell is being edited along with the coordinates of the cell in edit mode. Go ahead and add these two properties to the App class’ state property:

cellEdit: false, // whether or not any cell is in edit mode
editingCell: '', // a string representation of the coordinates for the cell being edited

By default, when the app loads, we assume a cell can’t be in edit mode. Next, we should add a visible textual element when a cell is in edit mode and hidden when no cells are being edited. To give the user additional context, the text in the element will include the coordinates of the cell that they’re editing.

To make sure our helpful, informative text is noticeable, we’ll place it in a tag. Add the following directly below the FlexGrid JSX markup:

<h5 style={{ display: this.state.cellEdit ? 'block' : 'none' }}>
  Currently editing cell at { this.state.cellEdit }
</h5>

All of that code is pretty fundamental. React - it was a piece of cake, right?! Now for the big finale...connecting the new state properties we created to FlexGrid events. Surely this must require some complex observable handlers or React anti-patterns, right?

Nope! We can hook up the FlexGrid's events to component class functions just like you'd expect from a React component you've written yourself. First, add the handler functions to the App class:

beginEdit(grid) {
  this.setState({
    cellEdit: true,
    editingCell: '{' + grid.selection.col + ', ' + grid.selection.row + '}',
  });
}

finishEdit() {
  this.setState({
    cellEdit: false,
  });
}

Again, some pretty straightforward React component functions are designed to update the state based on whether or not a cell is being edited. Note the grid object passed to the beginEdit function. FlexGrid will automatically pass relevant context to all of its event handlers. To figure out what information is passed for a specific event, consult the extensive FlexGrid API documentation.

To finish off this handy new feature, we have to tell FlexGrid to call these event handlers. Fortunately, because FlexGrid is a native React component, we can easily hook up these handlers in markup. Just add these properties to FlexGrid's declaration:

<FlexGrid itemsSource={this.state.data} beginningEdit={this.beginEdit.bind(this)} cellEditEnded={this.finishEdit.bind(this)} />

When all is said and done, your App class should look like this:

import React from 'react';
import ReactDom from 'react-dom';
import './styles.css';

import '@grapecity/wijmo.styles/wijmo.css';
import * as wjcGrid from '@grapecity/wijmo.react.grid';

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [
        { id: Math.floor(Math.random() * 1000, customer: 'Gia Shields', sale: Math.random() * 100000 },
        { id: Math.floor(Math.random() * 1000, customer: 'Jayden Foster', sale: Math.random() * 100000 },
        { id: Math.floor(Math.random() * 1000, customer: 'Selena Casey', sale: Math.random() * 100000 }, ]
    };
  }

  beginEdit(grid) {
    this.setState({
      cellEdit: true,
      editingCell: '{' + grid.selection.col + ', ' + grid.selection.row + '}',
    });
  }

  finishEdit() {
    this.setState({
      cellEdit: false,
    });
  }

  render() {
    return (
      <div>
        <wjcGrid.FlexGrid itemsSource={this.state.data} beginningEdit={this.beginEdit.bind(this)} cellEditEnded={this.finishEdit.bind(this)} />
        <h5 style={{ display: this.state.cellEdit ? 'block' : 'none' }}>
          Currently editing cell at { this.state.editingCell }
        </h5>
      </div>
    );
  }
}

export default App;

When you're all set, run your app in play around with FlexGrid in the browser! To see the events in action, double-click on any cell in FlexGrid. The beginningEdit event is immediately dispatched, and the App component's state is updating, showing the label with the proper cell coordinates. If you click outside of the grid, the label should disappear.

grid editing

Automatically Update FlexGrid with Data Binding

Now that our app handles displaying some data in a FlexGrid component and responds to our users' edit events, maybe it would be helpful to provide a form for users to add another sale to our list of sales data. Providing a form to update the state shouldn't be too hard, but how can we ensure that change propagates to the datagrid component?

Remember earlier when I had mentioned that we would be returning to the state-bound itemsSource property of FlexGrid? If you guessed that passing a state property to the FlexGrid component automatically provides two-way binding, you are correct!

Since the datagrid's data is already bound to a state property, all the app needs to do is update that property, and FlexGrid will update accordingly. Since each user in our system has 3 unique characteristics - an order id, a customer name, and a sale price - add three new corresponding properties to the App class' state:

saleId: null,
customerName: '',
saleAmount: null,

Next, we'll add a couple of quick functions that update the state with input from the 'add user' form and allow the App component to add a new object to the stateful user's array:

addSale() {
  if(this.state.saleId === null || this.state.customerName.length === 0 || this.state.saleAmount === null) {
    return;
  }
  this.setState({
    data: [
      ...this.state.data,
      { id: this.state.saleId, customer: this.state.customerName, sale: this.state.saleAmount },
    ],
    saleId: null,
    customerName: '',
    saleAmount: null,
  });
}

Again, these functions are just plain old React component class functions that will allow components to update the app's state in specific ways. The last step is to add the actual markup for the form:

<h4>Add Sale</h4>
<div>
  <label htmlFor="id">Sale ID: </label>
  <input type="text" id="id" value={this.state.saleId} onChange={this.idUpdate.bind(this)} />
</div>
<br />
<div>
  <label htmlFor="customerName">Customer Name: </label>
  <input type="text" id="customerName" value={this.state.customerName} onChange={this.customerUpdate.bind(this)} />
</div>
<br />
<div>
<label htmlFor="saleAmount">Sale Amount: </label>
  <input type="text" id="saleAmount" value={this.state.saleAmount} onChange={this.saleUpdate.bind(this)} />
</div>
<br />
<input type="button" value="Add Sale" onClick={() => this.addSale()} />

We've also tied a few methods to these onChange events. You can see them outlined below:

idUpdate(event) {
  this.setState({ saleId: event.target.value });
}

customerUpdate(event) {
  this.setState({ customerName: event.target.value });
}

saleUpdaet(event) {
  this.setState({ saleAmount: event.target.value });
}

Now that we've got all of that done, we're ready to take one last look at the code before we run our application:

class App extends React.Component {
  constructor(){
    this.state = {
      data: [
        { id: Math.floor(Math.random() * 100), customer: 'Gia Shields', sale: Math.random() * 100000 },
        { id: Math.floor(Math.random() * 100), customer: 'Jayden Foster', sale: Math.random() * 100000 },
        { id: Math.floor(Math.random() * 100), customer: 'Selena Casey', sale: Math.random() * 100000 },
      ],
      cellEdit: false,
      editingCell: '',
      saleId: null,
      customerName: '',
      saleAmount: null
    };
  }

  beginEdit(grid) {
    this.setState({
      cellEdit: true,
      editingCell: '{' + grid.selection.col + ', ' + grid.selection.row + '}'
    });
  }

  finishEdit() {
    this.setState({
      cellEdit: false
    });
  }

  addSale() {
    if(this.state.saleId === null || this.state.customerName.length === 0 || this.state.saleAmount === null) {
      return;
    }
    this.setState({
      data: [
        ...this.state.data,
        { id: this.state.saleId, customer: this.state.customerName, sale: this.state.saleAmount },
      ],
      saleId: null,
      customerName: '',
      saleAmount: null,
    });
  }

  idUpdate(event) {
    this.setState({ saleId: event.target.value });
  }

  customerUpdate(event) {
    this.setState({ customerName: event.target.value });
  }

  saleUpdate(event) {
    this.setState({ saleAmount: event.target.value });
  }

  render() {
    return(
      <div>
        <wjcGrid.FlexGrid itemsSource={this.state.data} beginningEdit={this.beginEdit.bind(this)} cellEditEnded={this.finishEdit.bind(this)}/>
        <h5 style={{ display: this.state.cellEdit ? 'block' : 'none' }}>
          Currently editing cell at {this.state.editingCell}
        </h5>
        <h4>Add Sale</h4>
        <div>
          <label htmlFor="id">Sale ID:</label>
          <input type="text" id="id" value={this.state.saleId} onChange={this.idUpdate.bind(this)} />
        </div>
        <div>
          <label htmlFor="id">Customer Name:</label>
          <input type="text" id="id" value={this.state.customerName} onChange={this.customerUpdate.bind(this)} />
        </div>
        <div>
          <label htmlFor="id">Sale Amount:</label>
          <input type="text" id="id" value={this.state.saleAmount} onChange={this.saleUpdate.bind(this)} />
        </div>
        <input type="button" value="Add Sale" onClick={() => this.addSale()} />
      </div>
    );
  }
}

ReactDom.render(<App />, document.getElementById('root');

If everything looks good, go ahead and start your app! You should see a brief form that accepts 3 inputs from users. If you fill it out and click the "Add Sale" button, you should see the grid immediately update with the new sale information you just added. That's the magic of FlexGrid's support for native two-way data binding.

grid with form

The form we created demonstrates one direction of the two-way dat abinding setup between the app's state and FlexGrid. What about the other direction? If you're using the React Developer Tools, you can see it in action right away!

Open up the dev tools and examine the app's state. You should see the data array with all of the current user objects. If you edit one of the rows in the grid (by double-clicking in a cell), you'll see the app's state immediately update to reflect the changes.

There you have it! Quick, easy, and natural two-way data binding with FlexGrid and React! I won't inundate you with more code, but I'll leave you with one last hint: there's an easier way to do what we just did with FlexGrid. If you're intrigued, check out FlexGrid's allowAddNew property.

Take the Next Step: Build Your Own FlexGrid App

If you're a huge React fan like I am and the FlexGrid examples above pique your interest, you can give Wijmo a try for yourself! Join the thousands of users and companies who use Wijmo to supercharge their UI development workflows.

"We purchased Wijmo, and their team is doing a great job: good-looking, well-thought-out architecture; documentation; keeping up with the ever-changing landscape like no others."

- Bj Jeoing, Cisco

If my words still haven't convinced you, I encourage you to try FlexGrid and prove me wrong. We haven't stopped refining and improving our grid for 20 years, and we won't stop anytime soon.

Try Wijmo's controls

Download the latest version of Wijmo

Download Now!