Classes


Headings

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5

Heading 6


Paragraphs

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?

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?


.wysiwyg &.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.

Person riding a bicycle on city street

List and List.Item

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

Hardcoded List Items

Now we have <List /> and <List.Item /> created, we can use them to create a basic to-do list.

Using Array.map()

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!

New Challenger Approaches

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

Improving the API

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.

Composition

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.

Introducing Pagination

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.

Render a Table Instead?

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.

Further Improvement

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.