top | item 21630459

React Table is a “headless” UI library

257 points| cwackerfuss | 6 years ago |github.com

114 comments

order
[+] euoia|6 years ago|reply
Every few months I look at the state of table libraries on the web. Of course, it's great to have pagination, sorting, searching - these are the basics.

I have been impressed with jQuery DataTables. jQuery DataTables has a lot of features, including export to Excel. jQuery DataTables works with Vue without any issues so long as you never mutate the table data. Mutating table data in Vue can be accommodated, but requires watching for data changes in Vue and making calls to the DataTables API.

I have a few questions about this library. Can it detect rows being clicked on (and emit an event, for example)? Can the searching be customized (I may want to display numbers in a locale-specific format, but match even when the search doesn't include the formatting)? Can sorting be customized (I may wish to the sorting for a field to depend on another, possibly hidden, field)?

What do people use in Vue-land for tables? Is there anything that approaches the feature set of jQuery DataTables?

[+] tannerlinsley|6 years ago|reply
- Exporting to excel is simple. You are provided the final data model after all processing/filtering/sorting/etc is done, and you are free to use whatever means you want to provide that data to your users, eg. The 'xlsx' npm package could do this easily.

- Searching/Filter is quite advanced. You can search/filter on any derived model of the data regardless of the display or format of that data.

- Sorting can also be 100% customized and can be configured to use any derived sorting mechanism that you choose or build, regardless of display or format.

[+] manigandham|6 years ago|reply
The difference is that jQuery directly modifies the DOM while React/Vue/Angular/Svelte are all designed to react to some data and automatically render based on it. The simplest table components create an HTML structure by repeating a <TR> for an array of data you pass in, with the columns being the keys. More complex ones let you define your own components to render each row and cell, and have internal state and logic to handle clicks, sorting, filtering, etc.

React Table in this version is headless meaning it just provides the backend functionality but requires you to implement the HTML rendering with your own JSX/components so you get the most control over the output. Detecting clicks is just putting a onclick handler for your rows. Searching is up to you wiring up a textbox and filtering the array of data you provide to the table. Sorting can be handled with custom sort functions.

Vue has plenty of table components too: https://vuejsexamples.com/tag/table/

Vue Tables 2 is a solid full-featured option: https://www.npmjs.com/package/vue-tables-2

Also AG-Grid for a universal JS option that competes with datatables: https://www.ag-grid.com/

[+] justaguyhere|6 years ago|reply
If you are impressed by datatables, you should check out Ag-Grid. It is much, much more powerful than datatables. The only negative thing about ag-grid is its price, otherwise it is a pleasure to work with.

I am not affiliated with them, just a very happy customer

[+] rajangdavis|6 years ago|reply
We use jQuery DataTables where I work and it seems more than adequate.

Supposed to set some time aside to investigate how to possibly port a small subsection of tables to use Vue Data Tables; it looks like there are a bevy of tools for Vue-based Data Tables here: https://madewithvuejs.com/blog/best-vue-js-datatables.

[+] swaggyBoatswain|6 years ago|reply
I worked at a company that migrated away from jQuery datatables. We chose Vue-good-table. Worked well but client side rendering mode had performance issues at 10k rows so we implemented a sorting algo in it.
[+] bbmario|6 years ago|reply
jQuery DataTables is unrivaled.
[+] max23_|6 years ago|reply
Whenever I need a table with pagination and export, jQuery DataTables is my go-to tool and it does the job well.
[+] georgewfraser|6 years ago|reply
I spent a ridiculous amount of time working on optimized table rendering in the early years of my company, and I came to a simple conclusion: if you want to display full-screen tables, with dense data, and scroll around fast, the only option is canvas. "Virtualized" HTML tables are always an order-of-magnitude slower, no matter how much effort you put into optimization.

The fundamental reason why you end up back at canvas is that if you are scrolling a full-screen table fast, even at 30 FPS you are going to have to rerender about half the table on each frame. So "virtualized DOM" doesn't really work; it's all about render speed. And canvas allows you to achieve unbeatable render speeds by specializing your drawing algorithm for your particular scenario.

[+] tannerlinsley|6 years ago|reply
I'm terribly sorry that you ended up in Canvas land for tables. I built and maintained Chart.js for a while, so I know how hard it can be to work with.

As for React Table, I have never run into a situation where drawing a table to canvas has ever been necessary. I guess I'll consider myself lucky, but I would still love to hear your use-case in a more structured format. Maybe a blog post?

[+] tomcam|6 years ago|reply
How do you deal with copy, paste, and accessibility issues?
[+] slig|6 years ago|reply
Isn't that what Google does on Google Sheets? I can only imagine the ungodly amount of work to get something like that working.
[+] RussianCow|6 years ago|reply
Using canvas also means you can't select text, copy/paste, open links, etc, which is a non-starter in most cases.
[+] doubletgl|6 years ago|reply
You're aware we have IntersectionObserver now?
[+] outsidetheparty|6 years ago|reply
I'm very curious how do people feel about the "headless component" UI strategy? First came across the concept at a conference recently -- React Table was one of the key examples the speaker gave, in fact -- and I find the idea intriguing, but I'm not quite sure yet whether I want to subscribe to the newsletter.

Is it a useful way to separate look-and-feel concerns from functional concerns, or is it just another layer of indirection?

[+] johnsoft|6 years ago|reply
I'm a fan. It's so refreshing to have all the HTML and CSS in your own codebase, under your control, instead of reading through a list of 50 sparsely-documented props only to realize that none of them quite do what you need.

Another example of this pattern is `downshift`, which is a headless autocomplete library: https://github.com/downshift-js/downshift

I would love to see a datepicker component that used this design. I have some choice words for the various datepicker libs I've used over my career and none of them are friendly.

[+] BigJono|6 years ago|reply
I've never used one, but it sounds like a great idea. 3rd party React components are a huge pain in the ass to work with. People do all sorts of bullshit like re-implement half of CSS in their component's API and half the time it's easier to just build the fucking thing yourself than learn all the arbitrary rules around customisation the author has conjured up.

The best reusable components are the ones that have exactly one look, which you're fine with, and are just plug in and go.

None of that is a problem with the logic behind the component though, just the display. So for something complex that has a bunch of logic behind it, it's a real nice idea to just be able to reuse that logic and whack some html and css over the top of it instead of having to read some 6 page doc every time you want to increase the width of a border or something.

[+] ng12|6 years ago|reply
I am extremely excited about it. I think of it as a form of IOC for front-end development. Almost constantly we run into a problem where a third party React library gets us 80% of what we want, but that last 20% is where we spend most of our time and where the most bugs are introduced. By taking full control of the front-end we can minimize the API wrangling and CSS hacks we need to get the component to play nice with our UI/UX spec.
[+] williamxd3|6 years ago|reply
I find it very useful, It works like a "backend" for components
[+] mmis1000|6 years ago|reply
Actually, many people do has same idea, but they don't call it 'headless component'. They instead call it 'renderless component'. Means the component itself render no ui element and delegate every ui part to something else. Google this word will give you a lot of similar ideas.
[+] MrOxiMoron|6 years ago|reply
I love this, I mostly do backend and the frontend work I do is usually making things like this so the frontend guy can just work on look and feel while I do the logic.
[+] grumblestumble|6 years ago|reply
I think the team behind this is somewhat trivializing this change by saying that a UI table library "has no business being in charge of your UI". Is the expectation is that the following are all bespoke, easy-to-implement features that application teams should rewrite from scratch and maintain internally, and should not be considered when looking at a library to deal with rendering tabular data in an application?

* Support for virtualized rows/columns * Support for fixed headers * Support for frozen columns * Support for resizable columns * Support for re-ordering columns * Dealing with page / container resizing. * Support for context menus in the context of all of the above * Support for master/detail views * Support for tree data

My take is that the inverse is true. Structure/Pagination/sorting/filtering of data sets is pretty trivial and in most cases the out-of-the-box functionality that libs provide for these is insufficient and ends up being overwritten anyway. The above list is exactly what I'm looking to outsource when looking at a grid library.

[+] tannerlinsley|6 years ago|reply
By team, I think you mean me. I'm flattered! :)

Being a headless UI library doesn't necessarily mean that it has no business being in charge of your UI, it's more about the way that you interact with the API. If you look closely at React Table, it absolutely does take charge of your UI via prop-getters and inversion-of-control integrated into your table markup.

There are plenty of table libraries that do exactly what you are referring to by handling the things you want to "outsource" pertaining to UI-specific features. Ag-Grid comes to mind here, which is a fantastic library and might do what you're looking for. However, the main takeaway here is that markup-bound APIs that are designed to be totally "in charge of your UI" may not always get out of the way when you need them to. Take it from a maintainer who has seen hundreds and hundreds of "issues" and "feature requests" that essentially amount to "how can I take back control of the [markup, styles, scrolling, pagination, resizing magic, frozen columns, etc]".

It's true that there is a bit more work involved in managing this on your own, but you're not really on your own after all. Fostering a good community of examples and resources around a low-level library like React Table v7 relieves most of that pain and you'll find that the amount of work to build and control your own table markup and styles is not only easy, but liberating.

Also, I don't really think it's fair to generalize structure/pagination/sorting/filtering as trivial tasks. Conceptually they are all very simple, for sure. But, marrying all of these features together in a way that is extremely performant across all of the many flexible permutations of features is very difficult. Ask any table library author and they will likely tell you that those 4 seemingly simple tasks are the ones that complicate everything else by a magnitude of difficulty.

Thanks for your feedback!

[+] burtonator|6 years ago|reply
I've been using react-table in Polar since the beginning and it's a great library.

We're using it in the document and annotation views and it provides pagination, sorting, etc.

I'm a bit nervous about this 7.0 release not providing a basic table UI as that was one of the wins for us migrating.

For example, here's a screenshot of the document repository:

https://getpolarized.io/#document-repository

... which is sort of the main view. React table allows you to sort by progress, creation time, update time, etc.

We used the same react table code to build the annotation viewer:

https://getpolarized.io/#annotation-viewer

One big issue we had was with context menus and selecting multiple items.

This doesn't come out of the box (of course) but I think platform-consistent multi-select is important so we had to implement all that functionality.

We're still a way from a more clear cut API for managing this stuff on the web + desktop + mobile.

I REALLY wish I could have web technology transparently work on mobile!

[+] tannerlinsley|6 years ago|reply
That's awesome! Soo cool to see it in your product! About being nervous, I don't think you should be! I know it's intimidating moving to v7 from v6, but it's pretty simple given the examples that we have in the repo thus far. If you still are getting the jitters, then DM me on Twitter! I would love to work something out to help you feel better about it. I offer sponsorships for prioritized support and even private consultation if needed. Don't be shy, just reach out!
[+] scarejunba|6 years ago|reply
I see. It's the backing data and state handling plus hooks (in the normal sense rather than React sense) to allow you to draw your own table. Very interesting.

Naturally, I imagine someone will make basic-react-table or something so you don't have to write the code to render the table. I appreciate that the bottom-most level of libraries is this customizable but frequently I don't want to draw all that code.

Still, perhaps the right place for that code is examples rather than a library. Hmm.

[+] acemarke|6 years ago|reply
And on that note, Tanner has put together a bunch of example CodeSandboxes for the various features [0] . For our own app, I basically copied most of the default rendering logic from those, applied styles to match the rest of our app, and we've been adding some additional APIs to the grid from there to suit our needs.

[0] https://github.com/tannerlinsley/react-table/blob/master/doc...

[+] quink|6 years ago|reply
I have put together the Material-UI Table component and react-table v7 for a project. Apart from the Typescript for v7 being a bit insufficient (but easy to work around it, and possibly fixed by now), it was an absolutely pleasant experience.

It’s almost like react-table v7 and {insert UI component library here} are made for each other and it’s incredibly valuable, more so than the previous react-table.

Absolute kudos to the developer and I look forward to UI component libraries writing their table display components to target the semantics of react-table v7.

This has some real potential for any UI library to get first-class table functionality without sweating and needlessly repeating the implementation details.

[+] proc0|6 years ago|reply
Hmmm this isn't srictly true. It's a React library after all, and React is the rendering "engine" here. Even their description says: "Hooks for building lightweight, fast and extendable datagrids for React". Therefore React is taking care of rendering. I think what they really mean by "It doesn't render it for you" is that you have to implement the rendering functions for the Table, which is more just like providing a UI plugin that has no "default" (but I'm even assuming React Table does have a simple default, so it's basically just an extensible UI plugin).
[+] tannerlinsley|6 years ago|reply
Yep! You're getting it now! Take a look at the examples and see just how easy it is to spin up your own table with React Table :)
[+] latortuga|6 years ago|reply
Have used React Table in production and it's a great, reliable library. Thanks Tanner!
[+] simion314|6 years ago|reply
is there a library that can render a lot of data as performant as native GUIs tabes/data-grids . In my experience just loading 1000 items at once it hangs in the browser native dom lay outing code, a good implementation won't create a GUI widget of each item but only for the visible ones and some buffer ones to have faster scrolling. Pagination and loading as you scroll is a hack, an example scenario would be like you would want to create a simple CSV editor and you want to load 1000+ rows , have sort-able, hide-able , rearangeble columns (with a decent toolkit you would just drop a DataGrid component and set the data provider
[+] addicted44|6 years ago|reply
The "headless" UI concepts promoted at this website feel to me like an attempt to shoehorn separation of templates and business logic which React has strongly resisted.

Any thoughts on whether this impression is right or wrong?

[+] sbilstein|6 years ago|reply
Formik does this for forms. It’s great.
[+] rubyn00bie|6 years ago|reply
So... is this pretty much providing a "headless" gui like coca does (e.g. UITableView), and then gives you a delegate or something which you implement for styling it (e.g. UITableViewDelegate)?
[+] bubbab|6 years ago|reply
React Table is soo good for making your own table library. The flexibility is insane, even in the previous version where you had render props + prop getters. I love the idea of headlessness in v7, although I'm kind of dreading the migration from v6 -> v7 :)
[+] hiccuphippo|6 years ago|reply
Fyi, the examples in codesandbox don't work for me unless I remove the serviceWorker.unregister() line.