Source: Image by Gerd Altmann from Pixabay

List Component in React-Admin: Simplified

Author: Deepanshu Galyan

Shiksha Engineering
8 min readNov 5, 2020

--

Most of the CMS applications revolve around the CRUD operations. The most opted way to display the data in CMS applications is using the LIST view. Therefore, it provides a strong use case to build a common code to render your list and handle list-related operations including pagination, rendering of each tuple, selection of tuple, deletion of the tuple, exporting the list as CSV sheet, and so on. To achieve the same, you can either opt for writing your own common LIST component that handles all these functionalities or you can speed up the process and opt for the React-Admin that provides all the above-mentioned functionalities to render a LIST component.

This article will walk you through the steps to build a list component using React-Admin. Therefore, I am assuming that you are familiar with the React-Admin library and its basic features. If not, you can refer to the article Building Admin Interface is no more boring or the official documentation of react-admin and come back here.

Before jumping on the code, I would like to mention two of the strongest features of react-admin LIST components that are otherwise, difficult to achieve:

  1. Pagination: Pagination is highly useful in LIST view when the total number of tuples in the list is high. The list can go up to 1000 tuples which makes it tedious to display the entire data in one go. Pagination makes it simpler to display such cases by dividing it into chunks and limiting the number of tuples per page.
  2. Export as CSV functionality: Another important use case is the functionality to download the listed data in a file. React-Admin provides an inbuilt single button click functionality to download the entire list of the interface as a CSV file.

List Component using Datagrid

This section focuses on building the list component using React-Admin, rendering the list component, and modifying the UI to suit the design requirement.

  1. Loading LIST resource in src/App.js:

The rendering starts with import the Resource component from React-Admin and passes the name prop and list prop. Pass your custom list component to the Resource component using the list prop of the Resource component.

As per the official definition, resource component is a configuration component that allows one to define sub-components for each of the admin views: list, edit, and create.

Source: Self

2. Custom data provider to adjust your APIs

To render the data, you will be required to fetch the information to display from the back end. For this article, I have used spring boot to create an API to fetch the below data in the JSON format that will be displayed in the list view. Also, I have used a custom Dataprovider to modify the request and response data as per the requirement. You can create your own Dataprovider to modify the data and to create your own Dataprovider, you can refer to the official documentation.

Source: Self

3. Building List Component

To build your list component, create a file like ListComponent.js, and check the below code.

i) The List Component provided by React-Admin handles the fetching of list data using the Dataprovider and renders the list layout that includes pagination, buttons, title, and filters (I have not used filters in the above example but if you require filters in your component, refer here).

ii) The rendering of each tuple of the list is delegated to the child component of the list component. There are three alternatives for the child component: Datagrid Component, SimpleList Component, and Custom Component. React-Admin provides you the first two. (Read the pros and cons of Datagrid and SimpleList here)

iii) Datagrid: Datagrid Component provided by React-Admin renders the list as a table. The number of columns depends on the number of fields it receives as its children and each field renders a specific data tuple mapped on the key same as that of the source name provided to that field.

iv) Field Components: The field component is responsible for handling the rendering of individual cells in the list component. The mandatory attributes you need to pass includes, ‘source’. The source defines the key in the list object returned by the API that you need to render. For example, the component with source value as “name” will render the “name” column and map the values on the key name “name” in the data set.

Source: Self

4. Performance of Datagrid

There are some performance challenges involved when the large data is displayed on a single page using Datagrid. This happens mainly as react-admin iterates over all the children of the Datagrid component and clones them which degrades the overall speed of the page. To overcome this obstacle, react-admin provides an optimized solution that can be achieved by adding the optimized prop to true in the Datagrid component. However, with optimized mode, the dynamic children, those which are displayed or hidden by checking permissions, cannot be used.

Creating a custom cell component

More often you will encounter a problem to customize the tuple as per the requirement of the product and design team where you will be required to display the content in a specific manner. React-Admin provides basic field and text components that are only customizable to a certain extent and majorly focus on displaying the content on the key mentioned in the source attribute of the component.

The above field component will display the data on the email key from the below data.

Source: Self

To handle cases where customized tuples are required, react-admin allows the users to create their own components. To mock the same requirement, I have created a custom component where the mobile phone icon is displayed along with +91 and the mobile number (provided by the API in response with the key name ‘contact’) of the user.

Source: Self

Call the custom component with source in your list component

Now, create a custom component in a separate file (example: PhoneContact.js) with the below code:

React-Admin, by default, pass props to the custom component with a ‘record’ key that contains the entire data of that particular tuple which can be used for rendering the information that is required to be displayed in that cell. The return function of the component returns the react fragment that will be displayed in the cell at the front end. In the above example, I have returned an empty React Fragment that contains <i> tag to display the mobile icon and <span> tag that returns the user’s contact information with ‘+91’ prefix.

Modifying UI of the tuple

React-Admin uses Material UI for styling the component. Now, Material UI has an inbuilt style, but you have the ability to add your custom CSS to redesign the interfaces as per the requirements.

Source: Self

The custom CSS is added using classes attribute in Field Components. To add the classes, either a higher-order component “withStyles” or hook “makeStyles” can be used.

To modify the headers, the custom class passed via “withStyles” is assigned to headerClassName prop and to modify the tuples, the custom class is assigned to cellClassName prop of Field Component.

Challenges and workaround

Challenge: A unique identifier is required in the list of data

As the List component iterates through each component, it requires a special identifier to perform Selection and Delete Operation on an individual tuple of the list data-set. If there is no unique identifier in the list, it imposes the following challenges:

  1. Data-sets with a common identifier will be considered as a single entity and the last definition will override the previous value. Therefore, the last value will be displayed on the front end.
  2. In pagination, the count will be different than the actual items displayed on the frontend as the data-sets with common id will be counted as one.
Source: Self

The above data list contains two objects with the same key-id ‘18830’. The second definition overrides the first one as it can be seen on the front end. The final value of other fields (name, email, contact, etc) displayed on the front end is from the second tuple (with name Dean Winchester).

Source: Self

Conclusion

The above article was dedicated to help you in developing basic LIST interfaces, modifying the UI of tuples of list interface, and creating your custom components for rendering nontrivial tuples.

In the next article of this series, I will be covering the usage of filters in List Interface which has been skipped in this article

--

--