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
| Prop | Type | Description |
|---|---|---|
children | ReactNode | List items to render |
onRefresh | () => void | Callback when pull-to-refresh is triggered |
onLoadmore | () => void | Callback when reaching the end of the list |
refresh-style | string | Refresh indicator style (e.g., "customCupertino") |
className | string | CSS class name |
style | CSSProperties | Inline 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
- Always set a height -
WebFListViewrequires a constrained height to enable scrolling - Use keys for list items - Provide unique
keyprops for efficient rendering - Debounce load more - Prevent duplicate load more requests with proper state management
- Show loading states - Display loading indicators during refresh/load operations
- Handle errors gracefully - Show error messages when data fetching fails
Performance Tips
- Use
WebFListViewinstead ofoverflow: autofor 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
- CSS Layout - Master layout techniques for list items
- Debugging & Performance - Optimize list rendering performance
- Hybrid UI - Integrate with Flutter UI components