react-native-big-list

repository·master·Indexed 20 days ago

https://github.com/marcocesarato/react-native-big-list

A high-performance, virtualized list for React Native designed to handle thousands of items efficiently. It utilizes a recycler pattern to reuse views, optimizing memory and CPU usage for smooth scrolling on Android, iOS, and web. The library provides a FlatList-like API and supports multi-column grids, sectioned lists with sticky headers, and integration with React Native Reanimated 2 for UI-thread animations.

Tokens
14.9K
Snippets
50
Records
70
Agent score
68%

What's inside react-native-big-list

  1. Introduction to React Native Big List

    master

    React Native Big List is a high-performance list view designed for React Native that supports complex layouts. It is designed to be a drop-in replacement for FlatList by using a similar API.

    Key features:

    • High Performance: Uses a recycler pattern focused on performance and memory usage, allowing for the rendering of thousands of items.
    • Cross-Platform: The library is fully JS native, making it compatible with Android, iOS, Windows, MacOS, Web, and Expo.
    • Recycler Pattern: Instead of destroying views when items scroll off-screen, the library reuses (recycles) those views for new items scrolling onto the screen. This reduces CPU usage and improves responsiveness.
  2. How react-native-big-list works

    master

    The library implements a recycler pattern to efficiently display large sets of data. Instead of destroying views when an item scrolls off-screen, the recycler reuses those existing views for new items scrolling onto the screen. This approach significantly improves responsiveness and reduces power consumption.

    Note: If the list cannot render items fast enough during rapid scrolling, non-rendered components may appear as blank space.

  3. Use compatibility props for FlatList replacement

    master
    The library provides several compatibility props that mirror standard React Native FlatList props. While these work, they are intended as aliases for the library's optimized props. As a best practice, you should use the library's native props instead of these aliases when creating new lists.
  4. How Reanimated integration works in BigList

    master

    BigList is designed to forward Reanimated worklet handlers to the underlying ScrollView without interfering with its own virtualization engine. This architecture provides three main benefits:

    1. UI Thread Performance: Reanimated worklets execute on the UI thread, ensuring animations remain smooth even if the JS thread is busy.
    2. Virtualization Integrity: BigList's internal scroll handling continues to manage efficient item rendering and memory usage.
    3. Parallel Execution: Both the animation worklets and BigList's virtualization logic run in parallel without blocking each other.
  5. How the Recycler pattern works in React Native Big List

    master

    React Native Big List utilizes a recycler mechanism to efficiently display large datasets.

    The Lifecycle of a View:

    1. Creation: The recycler dynamically creates elements as they are needed for the viewport.
    2. Recycling: When an item scrolls off-screen, its view is not destroyed. Instead, the view is kept in memory and reused for the next item that scrolls onto the screen.
    3. Performance Benefit: This reuse minimizes the overhead of creating and destroying components, which improves app responsiveness and reduces power consumption.

    Note on Rendering Speed: If the list cannot render items fast enough to keep up with scrolling, non-rendered components may temporarily appear as blank space.

  6. Data formats for BigList standard lists

    master

    The data prop for a standard BigList accepts a plain array. You can use simple primitive arrays or arrays of objects.

    Primitive array example: [1, 2, 3, 4, 5, 6]

    Object array example: [{ label: "1", value: 1 }, { label: "2", value: 2 }]

    // Primitive array
    [1, 2, 3, 4, 5, 6 /* ... */];
    
    // Object array
    [
      { label: "1", value: 1 /* ... */ },
      { label: "2", value: 2 /* ... */ },
      /* ... */
    ];
  7. How BigList works in test environments

    master

    BigList is designed to work in unit and integration tests without requiring actual layout measurements.

    In production, BigList relies on onLayout events to determine the container's height and decide which items to render. In test environments (like Jest with React Native Testing Library), these layout events typically do not fire because there is no actual rendering engine performing layout.

    To handle this, BigList automatically detects when the container height is 0 and falls back to a default batch size. This ensures that items are rendered and available for assertion even when no layout has occurred.

  8. Deploy the documentation website to GitHub Pages

    master

    To deploy the website to GitHub Pages, use the yarn deploy command. You must provide your GitHub username via the GIT_USER environment variable and set USE_SSH=true. This command builds the site and pushes the content to the gh-pages branch.

    GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy
  9. Test BigList components with React Native Testing Library

    master

    You can test BigList components using @testing-library/react-native. Because BigList renders items even without layout measurements in test mode, you can directly query for items using testID or text content.

    Key behaviors in tests:

    • No layout simulation needed: You do not need to mock container dimensions or trigger layout events.
    • Automatic rendering: BigList renders items up to a reasonable limit when container height is 0.
    • renderItem execution: Your renderItem function is called for each item in your data, allowing for standard JSX assertions.
    import { render, screen } from '@testing-library/react-native';
    import BigList from 'react-native-big-list';
    
    test('renders items correctly', () => {
      const data = [
        { id: '1', text: 'First' },
        { id: '2', text: 'Second' },
      ];
    
      const renderItem = ({ item }) => (
        <Text testID={`item-${item.id}`}>{item.text}</Text>
      );
    
      render(
        <BigList
          data={data}
          renderItem={renderItem}
          itemHeight={50}
        />
      );
    
      expect(screen.getByTestId('item-1')).toHaveTextContent('First');
      expect(screen.getByTestId('item-2')).toHaveTextContent('Second');
    });
  10. Use a standard list with BigList

    master

    To implement a standard list, you must provide a data prop, which is a plain array of items you want to render.

    When using BigList for a standard list, you must also provide specific height props for the header, footer, and items to ensure correct layout and performance:

    • itemHeight: Required. The height of each individual item.
    • headerHeight: Required if you want to display a header.
    • footerHeight: Required if you want to display a footer.

    Commonly used render props include:

    • renderItem: Function to render each item in the list.
    • renderEmpty: Function to render a component when the list is empty.
    • renderHeader: Function to render the header component.
    • renderFooter: Function to render the footer component.
    import BigList from "react-native-big-list";
    
    const data = [
      { label: "1", value: 1 },
      { label: "2", value: 2 },
      { label: "3", value: 3 },
      // ...
    ];
    
    const renderItem = ({ item, index }) => (
      <MyListItem label={item.label} value={item.value} />
    );
    const renderEmpty = () => <MyEmpty />;
    const renderHeader = () => <MyHeader />;
    const renderFooter = () => <MyFooter />;
    
    return (
      <BigList
        data={data}
        renderItem={renderItem}
        renderEmpty={renderEmpty}
        renderHeader={renderHeader}
        renderFooter={renderFooter}
        itemHeight={50} // Required
        headerHeight={90} // Required to show header
        footerHeight={100} // Required to show footer
      />
    );