Layout Components in React part 2 : List Items

ReactReact Patterns

Friday, April 12, 2024

A common scenario in building application layouts involves the repetitive rendering of lists. To streamline this process, developers often resort to a list item pattern. This pattern involves encapsulating the rendering logic into a reusable component, thereby avoiding redundant code blocks. One key feature of this pattern is the ability to pass a custom component as a prop, which dynamically renders each item based on the provided data.

Let's delve into this pattern using two example components: LargeProductListItem and SmallProductListItem. Each component is responsible for rendering product information, but they vary in layout and level of detail.

Consider two components as bellow :

import React from 'react';

const LargeProductListItem = ({product}) => {
    const {name, price, description, rating} = product
    return (
        <>
            <h3>{name}</h3>
            <p>{price}</p>
            <h3>Description</h3>
            <p>{description}</p>
            <p>Average Rating: {rating}</p>
        </>
    );
};

export default LargeProductListItem;
import React from 'react';

const SmallProductListItem = ({product}) => {
    const {name, price} = product
    return (
        <h3>{name} - {price}</h3>
    );
};

export default SmallProductListItem;

Now, let's consider a small dataset of products:

const products = [{
    name: 'Flat-Screen TV',
    price: '$300',
    description: 'Huge LCD screen, a great deal',
    rating: 4.5,
}, {
    name: 'Basketball',
    price: '$10',
    description: 'Just like the pros use',
    rating: 3.8,
}, {
    name: 'Running Shoes',
    price: '$120',
    description: 'State-of-the-art technology for optimum running',
    rating: 4.2,
}];

To dynamically render these components without repeating mapping logic, we'll create a wrapper component called RegularList:

import React from 'react';

const RegularList = ({items, resourceName, itemComponent: ItemComponent}) => {
    return (
        <>
            {items.map((item, i) => (   
                    <ItemComponent key={i} {...{[resourceName]: item}}/>
            ))}
        </>
    );
};

export default RegularList;

With this pattern, we can effortlessly render lists by passing our data to the RegularList wrapper alongside the custom component. The wrapper intelligently handles the rendering process, making it a versatile solution for various applications.