React Virtual List Component which worked with animation
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The render system provides the type interfaces and patterns for rendering list items with proper positioning and styling support.
The core render function interface that defines how individual list items are rendered.
/**
* Function type for rendering individual list items (available through ListProps.children)
* @param item - The data item to render
* @param index - Position of the item in the data array
* @param props - Additional rendering properties
* @returns React node representing the rendered item
*/
type RenderFunc<T> = (
item: T,
index: number,
props: {
style: React.CSSProperties;
offsetX: number;
}
) => React.ReactNode;The render function is called for each visible item and receives:
item: The actual data from the data arrayindex: The item's position in the original data arrayprops.style: CSS styles for positioning (crucial for virtualization)props.offsetX: Horizontal offset for horizontal scrollingUsage Examples:
import List from "rc-virtual-list";
// Basic render function
<List data={items} height={300} itemHeight={50} itemKey="id">
{(item, index) => (
<div>{item.name}</div>
)}
</List>
// Using all render parameters
<List data={items} height={300} itemHeight={50} itemKey="id">
{(item, index, { style, offsetX }) => (
<div
style={style} // Important: Apply the provided style
className={index % 2 === 0 ? 'even' : 'odd'}
>
<span>#{index}: {item.name}</span>
{offsetX > 0 && <span>Offset: {offsetX}px</span>}
</div>
)}
</List>
// Complex item rendering
<List data={products} height={400} itemHeight={80} itemKey="id">
{(product, index, { style }) => (
<div style={style} className="product-item">
<img src={product.image} alt={product.name} />
<div className="product-details">
<h3>{product.name}</h3>
<p>{product.description}</p>
<span className="price">${product.price}</span>
</div>
</div>
)}
</List>Information provided to the extraRender function for advanced rendering scenarios.
/**
* Information provided to extraRender function
*/
interface ExtraRenderInfo {
/** First visible item index */
start: number;
/** Last visible item index */
end: number;
/** Whether virtualization is currently active */
virtual: boolean;
/** Current horizontal offset for horizontal scrolling */
offsetX: number;
/** Current vertical offset */
offsetY: number;
/** Whether the list is in RTL mode */
rtl: boolean;
/** Function to get size information for items */
getSize: GetSize;
}Usage Example:
import List from "rc-virtual-list";
const ListWithExtra = () => {
const extraRender = (info: ExtraRenderInfo) => {
return (
<div style={{
position: 'absolute',
top: 0,
right: 0,
padding: '8px',
background: 'rgba(0,0,0,0.5)',
color: 'white'
}}>
Showing items {info.start}-{info.end}
{info.virtual && ' (virtualized)'}
</div>
);
};
return (
<List
data={data}
height={300}
itemHeight={50}
itemKey="id"
extraRender={extraRender}
>
{(item) => <div>{item.name}</div>}
</List>
);
};/**
* Function to get size information for item ranges
* @param startKey - Starting item key
* @param endKey - Ending item key (optional)
* @returns Size bounds information
*/
type GetSize = (
startKey: React.Key,
endKey?: React.Key
) => {
top: number;
bottom: number;
};/**
* Shared configuration object passed through the rendering system
*/
interface SharedConfig<T> {
/** Function to extract keys from data items */
getKey: (item: T) => React.Key;
}/**
* Function type for extracting unique keys from data items
*/
type GetKey<T> = (item: T) => React.Key;Always apply the provided style prop to maintain proper virtualization:
// ✅ Correct - applies positioning styles
{(item, index, { style }) => (
<div style={style}>
{item.content}
</div>
)}
// ❌ Incorrect - virtualization will break
{(item, index, { style }) => (
<div>
{item.content}
</div>
)}Use stable, unique keys for optimal performance:
// ✅ Good - stable unique key
itemKey="id"
// ✅ Good - function returning stable key
itemKey={(item) => item.uniqueId}
// ❌ Poor - unstable key
itemKey={(item) => Math.random()}React.memo for complex item components// ✅ Optimized render function
const ItemComponent = React.memo(({ item, style }) => (
<div style={style}>
<h3>{item.title}</h3>
<p>{item.description}</p>
</div>
));
<List data={data} height={300} itemHeight={80} itemKey="id">
{(item, index, { style }) => (
<ItemComponent item={item} style={style} />
)}
</List>Install with Tessl CLI
npx tessl i tessl/npm-rc-virtual-list