Rohit Kalkur
rovolution
@Rovolutionary
Software Engineer
@
Problem
- Social Table's Event Dashboard is the first view customers see after logging in
- Old dashboard was legacy code built with Knockout.js / jQuery
- No pagination (all data rows created in DOM)
What Did We Want?
- Pagination
- Minimal amount of nodes in the DOM
- Filtering
- A clean, sensible code architecture
- A better design wouldn't hurt either!
Fixed Data Table!
- FixedDataTable can be used to show our list of events
- Consists of 3 types of components
- Table
- Column
- ColumnGroup
Fixed Data Table!
- Can be customized via props (which are well documented)
- Takes props for literally anything and everything
- width (required)
- height (required)
- rowsCount (required)
- column content
- scroll position
Fixed Data Table!
- The most important prop is rowGetter
- This is used by the component to retrieve the data at a given row
- dataKey property of Column is used to access the data for the cell from the row
Fixed Data Table!
data
{
"id": 0,
"name": "Bob",
"age": 10
}
{
"id": 1,
"name": "Jane",
"age": 20
}
<Table
rowHeight={50}
rowGetter={rowGetter}
rowsCount={data.length}
width={5000}
height={5000}>
<Column
label="Name"
width={3000}
dataKey={'name'}>
<Column
label="Age"
width={3000}
dataKey={'age'}>
</Table>
Name
Age
Bob
Jane
10
20
function rowGetter(rowIndex) {
return data[rowIndex];
}
Fixed Data Table!
- Easy to see how this works for static data set, but what about dynamic data (for ex: pagination) ?
- FixedDataTable examples all use custom data stores for handling data fetching logic
EventsStore
- Holds the list of events that the events table uses
- FixedDataTable's rowGetter prop is set to a method implemented directly on the store. For ex.
- rowGetter = EventsStore.getEventAt
-
User actions trigger methods on the store
- EventsStore.fetch()
- EventsStore.delete()
EventsStore
- EventStore is also an event emitter
- Whenever store's contents are updated via fetch(), delete(eventId), etc..., it updates its data and triggers an 'update' event
- events-table component is subscribed to 'update' event, and when an update occurs, it calls setState() and updates its events state data.
Code Architecture
EventsStore.js
events-table.jsx
'update'
EventsStore.fetch()
_updateEvents: function() {
this.setState({
events: EventsStore.getEvents()
});
}
componentWillMount: function() {
EventsStore.on('update', this._updateEvents);
}
EventsStore
- But what about pagination???
- Pagination logic can be also be handled by the store as well!
- For instance, let us say our user has 600 events, and we have a page size of 200
- Pass 600 in for the rowCount prop for Table.
- When getEventAt() is called via rowGetter, you can create whatever custom page retrieval logic you want!
EventsStore
- For example, if getEventAt() has been called for 75% of the data on the current page, then go ahead and optimistically fetch the next page!
EventsStore
- All data fetching/pagination logic happens in the store itself
- Stores become highly logical
- Facebook realized that people were implementing certain logic patterns repeatedly in stores (such as pagination), and created abstractions for these in their Relay framework
Conclusion
- FixedDataTable is an awesome component for creating customizable data tables in React
- Creating a separate data store for handling the data allows you to cleanly decouple data fetching/manipulation logic from display and leads to more understandable code!
- Griddle is a fixed data table alternative that is more fully featured
FixedDataTable
By Rohit Kalkur
FixedDataTable
My experiences using the FixedDataTable React component by Facebook
- 6,933