- ReactDataGrid is a React component for displaying tabular data, built from the ground up for 2023, by a team with 20+ years of experience building datagrids.
- It is very light weight without compromising on features, thanks to a combination of thoughtful design, modern tooling & ecosystem, plugin architecture, and ES6 modules. More on this below.
- Built in React for React, with TypeScript.
What is EUXDT ReactDataGrid?
EUXDT (Enterprise User eXperience Data Toolkit) is a toolkit for visualizing data in enterprise applications. The primary component in this library is a ReactDataGrid that can be used to display data in a tabular or hierarchical format.
A Trip down the memory lane
Depending on when you began your journey with us, you are using one of our many different DataGrid components (Or are completely unfamiliar with us , in which case, welcome!). Our DataGrid history starts way back in the early 2000's. We built what was the single most popular DataGrid component in the world for Flex and Flash (for those of you who remember what that even is!), used by tens of thousands of developers worldwide including more than 50% of the Fortune 500 companies. And then came the infamous Steve Jobs Flash killer letter. We saw the writing on the wall and began porting our datagrid to HTML - with jQuery, and then to Android and to iOS and then to react back in 2017, and now again in 2023! These are only the published products. In house, we have one for angular, vue, web components, and others. In addition to offering off the shelf datagrid products, we have built extensions and custom features for hundreds if not thousands of customers over the years.
Material UI (And others)
If you are using React, there is a good chance you are using MUI. When we wrote this product, integration with MUI was among the most important success criteria. As you can see in the demos, as soon as you plug in the Material Adapter, all of the primitives - icon buttons, checkboxes, text fields, dropdowns, date pickers, everything switches over to the adapter's rendering. An added benefit of this is, all the Material styling, accessability and theming features are automatically available to the grid, as you can see from the material examples. The filters, editors, toolbar actions, are all MUI components, and the grid knows how to integrate with them. This is what we mean by first class integration with MUI. As of this writing, adapters for Bootstrap, Ant Design, and Chakra are in the works. Please let us know if you would like to see an adapter for a specific framework.
However, we wanted to ensure that you don't have to use MUI or any other library to use our product. In our entire spirit of keeping our package size small and dependency free, we architected the grid to be extremely pluggable. The grid is a tree of nodes, and every node returns a React Element. The grid does not really care what that react element is, just needs a react element. It could be a Material UI element, or a Bootstrap element, or a simple DIV. A natural consequence of this approach was a highly customizable rendering engine. If you look at our MUI adapter, its barely a couple hundred lines of code, most of which is just which icons to use where. This speaks to how easy it is to radically customize the look and feel of the grid.
DataGrids are complex components. They are not just a table. They have a lot of functionality, and a lot of code. Many commercial DataGrids, ours included, have built up a ton of legacy bloat. This is not a bad thing. It is a natural consequence of building a product over a long period of time. However, it does mean that the codebase is not as lean as it could be. We've found ourselves in this situation - in order to meet customer needs, anytime we get a feature request, we've tried to add it to the core product. What we've realized over the years is that this code is being used by a very small percentage of our customers. Today, if you were to use any of the commercial datagrids (our older products included), you would be adding 500K-1MB or more to your bundle. This is a lot of code, and it increases the payload and memory footprint of your application. It increases the amount of time it takes for your app to compile, which increases the iterative code/test cycle for your developers, hinders HMR (Hot module reload), and makes developers less productive. A lot of older components are built in a way that does not allow for tree shaking. One way to check to see if your current library is using treeshaking is to look at the package.json and check to see if sideEffects is false. Our product, comes in a tiny 190KB, side-effect free package. If you don't use all the features, it is < 100K because of the tree shaking (discussed below). This is literally a fraction of our older products and most other commercial grids, without compromising on features. You can also spin up a simple react application and import our grid and compare it to the size of the final bundle, and you will see how much little this library will add to your application.
Evolution of Webpack, Tree Shaking, and ES6 Modules
Inception : The DataGrid Edition
If you haven't seen the movie, apologies :-). If you have, then the analogy will make sense. We used the grid to implement the features of the grid! The settings popup that lets you control column visibility? Its a hierarchical DataGrid component. The Manage Settings popup that allows you to switch between views? Yep. Another DataGrid. The multi select and date dropdown filters? you guessed it, a DataGrid inside a dropdown. The Filter Builder? A DataGrid! This embedding of the grid inside a grid has helped us reduce our code footprint, and also allowed us to build a lot of functionality in a very short amount of time. Finally, So much of the code inside grid-core is recursive. Its functions calling themselves - because end of the day its a component tree. A tree of virtual nodes that translates to the React VDOM, that translates to the browser DOM. Trees and recursion are like peas in a pod. Conceptually, so much of what we're doing in code feels the same way. Rows are hierarchical, but so are columns. With small reusable idempotent functions, we've tried to keep our code as concise as possible. And the results speak for themselves. The grid has most of the heavily used features of our older products, but with a much smaller footprint.
Internet Explorer (RIP)
Pluggability over Configuration
A common complaint we got over our older products was that although it was extremely powerful, it had way too many properties. We let you customize a million things using boolean/numeric flags. And no matter how many flags we provided, we ALWAYS had requirements from customers that made us go "just use the renderer". These flags led to confusion, bugs, and in general a poor developer experience because as the number of flags increased, the combinations increase exponentially, and it becomes impossible to test all the combinations. We decided to take a different approach this time around. We decided to make the grid as pluggable as possible. As an example, instead of giving you a dozen flags for verticalGridLines, verticalGridLineThickness, verticalGridLineColor, repeated at each nested levels (because they can be different), we just say - use custom css for global changes, and if not, use cellStyleFunction. Same effect, but much more powerful. We also made it incredibly easy to inject renderers, features and behaviors. We made pluggability a cornerstone of the design, and we used it ourselves extensively through out the core. For example, we used it to completely replace the rendering engine to use Material UI primitives in the adapter. And since the gridOptions is just an object, you can have a global config object that you destructure in all your configs. We actually do this in our own code, because (as we talked about in the Grid Inception section), we use the grid to implement the grid. So we have a global config object that we destructure in all our configs. This has made our codebase much more concise, and easier to maintain. This is how, when you plugin for example the material adapter in the main grid, all inner grids automatically inherit it.
While our grid supports a vast array of features out of the box, one of core design decisions was to make it very easy to customize the product. If you are a source customer, you will see our product has 3 libraries internally. Grid Core is a 0 dependency pure logic library. Does not even need react. It takes your data, and converts it into a large tree of nodes. Then there is Grid-React. This knows how to take these nodes, and convert them to React Elements. The only dependency here is react (version 16 or above). Finally, there is the grid-export. Where the only dependencies are jsPdf, excel-js, or whatever export library you choose. The demos also show how to plug in Material into grid-react, so you can completely swap out the grids built in primitives with Material components which goes to tell you how easy it is to customize our product. The grid core/react, comes in a tiny 190KB, side-effect free package. If you don't use all the features, it is < 100K because of the tree shaking mentioned above. This is literally 1/5th of our older products (and many other commercial ones as well).
One of our most prominent strength is our first class support for hierarchical/tree shaped data. We like to believe all data is essentially hierarchical. This is because data is nothing without relationships. We've built our component to support this. While most other grid components will show a simple master/detail or expand/collapse type rows, we've taken it many steps further, and integrated hierarchical filtering, floating rows that give your users context while scrolling, lazy loading at all levels, virtualized scrolling of hierarchical data, Selection Cascade, Group Headers, Very Large Hierarchical Grids, Inner Level Renderers with Locked Column Support and many more features built around this. Its very easy to write features with for flat data. Once you add an additional depth dimension, which is the case with most real world data, things get a lot more complicated. Support for complex hierarchical data has been a cornerstone of our products for over two decades, and we've carried on that DNA into this component.
We've been writing DataGrids for almost 2 decades now. We've written them in Flash, Flex, jQuery, DOJO, EXTjs, Angular, React, Vue, WebComponents, Android, iOS and this is our latest edition. We've learned a lot over the years, taken things that we would do differently if we were to start from scratch today, kept the things we got right, and distilled it into this component. While nothing is perfect, this product is the culmination of all our experience, and we are very proud of it. We hope you enjoy using it as much as we enjoyed building it.