Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium accusamus aperiam pariatur omnis mollitia placeat excepturi praesentium, eaque obcaecati illum, assumenda accusantium, velit rem saepe atque officia cumque. Possimus, tenetur?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium accusamus aperiam pariatur omnis mollitia placeat excepturi praesentium, eaque obcaecati illum, assumenda accusantium, velit rem saepe atque officia cumque. Possimus, tenetur?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium accusamus aperiam pariatur omnis mollitia placeat excepturi praesentium, eaque obcaecati illum, assumenda accusantium, velit rem saepe atque officia cumque. Possimus, tenetur?
&.with-lede
In this post, we'll be building a declarative React list rendering
component inspired by
Ant Design's List and
React Native's FlatList
to use in situations where you may regularly reach for
array.map()
. While JavaScript's array methods are amazing
modern additions to the language—they improve readability and foster
immutable data transformation—they're fairly limited when it comes to UI
rendering, but we can use them as a foundation for something better!
Over the next few examples, we'll refactor an
array.map()
example to use a newly created
ListView
, then start to introduce functionality designed to
cut boilerplate required to implement common patterns for organizing
collections of data.
Before we get started, we'll create a couple unstyled
List
and List.Item
components to use in the
rest of the examples. To follow along interactively, see this
CodeSandbox Project
and feel free to fork and customize/style the examples as we go then
share them with me on Twitter
Now we have <List />
and
<List.Item />
created, we can use them to create a
basic to-do list.
As our list continues to grow, we'll update to use a simple data
structure then start rendering a variable amount of items with
array.map()
—Don't forget the key prop!
So far, so good. The example above is a valid and standard approach in most React codebases. Over time, there will be other features we want to add to this list, such as filtering, sorting, and pagination. As the project continues to grow, the boilerplate supporting these patterns will get fragmented and inconsistent, unless we have a way to centralize them.
Let's start our alternative approach by creating
ListView
to be functionally equivalent to
array.map()
We can now refactor our application code to replace our
List.Item
rendering
With the foundation in place, let's add a few more props and, in doing so, add support for many more use-cases.
A quick note on what the newly added props do before we update the
example code. In each case, when these optional props are omitted, they
leave behind no trace of their existence rendering either
null
or a Fragment
accordingly.
At this point, the ListView itself is fully functional and gives us a nice declarative API to render the original example entirely. Are we done? Not nearly. Now we're ready to really get started! With a flexible foundation in place, we can now write a series of thin wrapper components to implement custom functionality or styles.
As our list length grows, one of the first additions we'll want to make
is the introduction of pagination. To support a traditional pagination
pattern, we'll wrap the ListView
with a specialized
PaginatedListView
.
Sidenote: If you're new to React Hooks, this recently updated free course from Kent Dodds & Egghead The Beginner's Guide to React is an excellent introduction to the topic.
To implement this in our example code, we'll need to add the
usePagination()
Hook, update the component name from
ListView
to PaginatedListView
, then add two
new props: currentPage
and perPage
.
We sure can. Let's swap out all the HTML in our example and semantically render a table without modifying anything below the surface and keep the pagination free.
To expand upon the examples above, here's a few features that can be implemented in just few lines in new composing components without modifying the underlying ListView at all:
Really, the possibilities are endless. Feel free to fork the CodeSandbox Project or give it a shot in your next side-project and let me know what you find!
I hope the examples above help to illustrate the value of a generic list rendering component and the power of React as a tool to standardize UI patterns irrespective of DOM elements rendered on screen.
For more information, be sure to check out Ant Design's List and React Native's FlatList excellent examples too.