Skip to Content
DocsDeveloper GuideCore ComponentsWebFListView

WebFListView

WebFListView is a performance-optimized component for rendering long scrollable lists in WebF. While overflow: auto works for basic scrolling, WebFListView provides superior performance for long lists with built-in pull-to-refresh and infinite scroll capabilities.


Why Use WebFListView?

DOM mutations in WebF are 20x cheaper than in browsers, but for displaying long lists (hundreds or thousands of items), WebFListView provides:

  • Optimized rendering for large datasets
  • Native pull-to-refresh with platform-specific styling (Cupertino/Material)
  • Load more / infinite scroll support
  • Better memory management for long lists
  • Smooth scrolling performance on mobile devices

Basic Usage

import { WebFListView } from '@openwebf/react-core-ui'; function BasicList() { const items = Array.from({ length: 100 }, (_, i) => i + 1); return ( <WebFListView> {items.map(item => ( <div key={item} style={{ padding: 16, borderBottom: '1px solid #eee' }}> Item {item} </div> ))} </WebFListView> ); }

Pull to Refresh

Enable pull-to-refresh functionality with the onRefresh prop:

import { WebFListView } from '@openwebf/react-core-ui'; function RefreshableList() { const [items, setItems] = useState(Array.from({ length: 20 }, (_, i) => i + 1)); const handleRefresh = () => { console.log('Refreshing...'); // Simulate data fetching setTimeout(() => { setItems(Array.from({ length: 20 }, (_, i) => i + 1)); console.log('Refresh complete'); }, 1500); }; return ( <WebFListView onRefresh={handleRefresh} style={{ height: 400 }} > {items.map(item => ( <div key={item} style={{ padding: 16, borderBottom: '1px solid #eee' }}> Item {item} </div> ))} </WebFListView> ); }

Load More (Infinite Scroll)

Implement infinite scrolling with the onLoadmore prop:

import { WebFListView } from '@openwebf/react-core-ui'; function InfiniteScrollList() { const [items, setItems] = useState(Array.from({ length: 15 }, (_, i) => i + 1)); const handleLoadMore = () => { console.log('Loading more...'); // Simulate loading more data setTimeout(() => { const newItems = Array.from({ length: 10 }, (_, i) => items.length + i + 1); setItems([...items, ...newItems]); console.log('Loaded more items'); }, 1000); }; return ( <WebFListView onLoadmore={handleLoadMore} style={{ height: 400 }} > {items.map(item => ( <div key={item} style={{ padding: 16, borderBottom: '1px solid #eee' }}> Item {item} </div> ))} </WebFListView> ); }

Refresh Styles

Customize the refresh indicator style with the refresh-style prop:

Custom Cupertino Style

<WebFListView refresh-style="customCupertino" onRefresh={handleRefresh} onLoadmore={handleLoadMore} style={{ height: 400 }} > {items.map(item => ( <div key={item} style={{ padding: 16, borderBottom: '1px solid #eee' }}> Item {item} </div> ))} </WebFListView>

Platform-Specific Components

For explicit platform styling, use the specialized components:

import { WebFListviewCupertino, WebFListviewMaterial } from '@openwebf/react-ui-kit'; // Cupertino (iOS) style <WebFListviewCupertino onRefresh={handleRefresh}> {items.map(item => ( <div key={item}>Item {item}</div> ))} </WebFListviewCupertino> // Material (Android) style <WebFListviewMaterial onRefresh={handleRefresh}> {items.map(item => ( <div key={item}>Item {item}</div> ))} </WebFListviewMaterial>

Props

WebFListView

PropTypeDescription
childrenReactNodeList items to render
onRefresh() => voidCallback when pull-to-refresh is triggered
onLoadmore() => voidCallback when reaching the end of the list
refresh-stylestringRefresh indicator style (e.g., "customCupertino")
classNamestringCSS class name
styleCSSPropertiesInline styles

Complete Example

import React, { useState } from 'react'; import { WebFListView } from '@openwebf/react-core-ui'; function CompleteListExample() { const [items, setItems] = useState(Array.from({ length: 15 }, (_, i) => i + 1)); const handleRefresh = () => { console.log('Refreshing...'); setTimeout(() => { setItems(Array.from({ length: 15 }, (_, i) => i + 1)); console.log('Refresh complete'); }, 1500); }; const handleLoadMore = () => { console.log('Loading more...'); setTimeout(() => { const newItems = Array.from({ length: 10 }, (_, i) => items.length + i + 1); setItems([...items, ...newItems]); console.log('Loaded more items'); }, 1000); }; return ( <WebFListView refresh-style="customCupertino" onRefresh={handleRefresh} onLoadmore={handleLoadMore} style={{ height: 600, border: '1px solid #e5e7eb', borderRadius: 8, background: '#ffffff' }} > {items.map(item => ( <div key={item} style={{ padding: 16, borderBottom: '1px solid #e5e7eb', background: item % 2 === 0 ? '#f9fafb' : '#ffffff' }} > <div style={{ fontWeight: 600, marginBottom: 4 }}> Item {item} </div> <div style={{ fontSize: '0.875rem', color: '#6b7280' }}> Description for item {item} </div> </div> ))} </WebFListView> ); }

Best Practices

  1. Always set a height - WebFListView requires a constrained height to enable scrolling
  2. Use keys for list items - Provide unique key props for efficient rendering
  3. Debounce load more - Prevent duplicate load more requests with proper state management
  4. Show loading states - Display loading indicators during refresh/load operations
  5. Handle errors gracefully - Show error messages when data fetching fails

Performance Tips

  • Use WebFListView instead of overflow: auto for lists with 100+ items
  • Avoid heavy computations inside list item render functions
  • Use React.memo() for list item components to prevent unnecessary re-renders
  • Keep list item heights consistent for better scroll performance
  • Lazy load images and heavy content within list items

Next Steps