React Window is a lightweight library for efficiently rendering large lists and grids in React applications. It uses virtualization to only render the items visible in the viewport, dramatically improving performance for lists with thousands of items. This guide walks through setting up and creating your first virtualized list using React Window with React, from installation to a working implementation. This is part 25 of a series on using React Window with React.
Prerequisites
Before you begin, make sure you have:
- Node.js version 14.0 or higher installed
- npm, yarn, or pnpm package manager
- A React project (version 16.8 or higher) or create-react-app setup
- Basic knowledge of React hooks (useState)
- Familiarity with JavaScript/TypeScript
Installation
Install React Window using your preferred package manager:
npm install react-window
Or with yarn:
yarn add react-window
Or with pnpm:
pnpm add react-window
After installation, your package.json should include:
{
"dependencies": {
"react-window": "^1.8.10",
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
Project Setup
React Window requires minimal setup. No additional configuration is needed beyond installation.
First Example / Basic Usage
Let's create a simple virtualized list component. Create a new file src/VirtualizedList.jsx:
// src/VirtualizedList.jsx
import React from 'react';
import { FixedSizeList } from 'react-window';
function VirtualizedList() {
// Generate a large array of items
const items = Array.from({ length: 10000 }, (_, i) => ({
id: i + 1,
name: `Item ${i + 1}`,
description: `This is item number ${i + 1}`
}));
// Row component that renders each item
const Row = ({ index, style }) => {
const item = items[index];
return (
<div
style={{
...style,
padding: '16px',
borderBottom: '1px solid #eee',
display: 'flex',
alignItems: 'center'
}}
>
<div>
<strong>{item.name}</strong>
<div style={{ fontSize: '14px', color: '#666' }}>
{item.description}
</div>
</div>
</div>
);
};
return (
<div style={{ padding: '20px' }}>
<h2>Virtualized List (10,000 items)</h2>
<FixedSizeList
height={600}
itemCount={items.length}
itemSize={60}
width="100%"
>
{Row}
</FixedSizeList>
</div>
);
}
export default VirtualizedList;
Now, update your App.jsx to use the virtualized list:
// src/App.jsx
import React from 'react';
import VirtualizedList from './VirtualizedList';
import './App.css';
function App() {
return (
<div className="App">
<h1>React Window Example</h1>
<VirtualizedList />
</div>
);
}
export default App;
This creates a virtualized list that efficiently renders 10,000 items by only displaying what's visible in the viewport.
Understanding the Basics
React Window uses virtualization to render only visible items:
- FixedSizeList: Component for lists with fixed item heights
- VariableSizeList: Component for lists with variable item heights
- height: Height of the visible area in pixels
- itemCount: Total number of items in the list
- itemSize: Height of each item (for FixedSizeList) or function (for VariableSizeList)
-
Row: Component that renders each item, receives
indexandstyleprops
Key concepts:
- Virtualization: Only renders visible items, improving performance
- Row Component: Function or component that renders each item
- Style Prop: Must be applied to the row element for correct positioning
- Item Size: Fixed height for FixedSizeList, function for VariableSizeList
Here's a simpler example with just text items:
// src/SimpleList.jsx
import React from 'react';
import { FixedSizeList } from 'react-window';
function SimpleList() {
const items = Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`);
const Row = ({ index, style }) => (
<div style={style}>
{items[index]}
</div>
);
return (
<FixedSizeList
height={400}
itemCount={items.length}
itemSize={50}
width="100%"
>
{Row}
</FixedSizeList>
);
}
export default SimpleList;
Practical Example / Building Something Real
Let's build a comprehensive data table with virtualization:
// src/VirtualizedDataTable.jsx
import React, { useState } from 'react';
import { FixedSizeList } from 'react-window';
function VirtualizedDataTable() {
const [data] = useState(() => {
return Array.from({ length: 5000 }, (_, i) => ({
id: i + 1,
name: `Employee ${i + 1}`,
email: `employee${i + 1}@example.com`,
department: ['Engineering', 'Marketing', 'Sales', 'HR'][i % 4],
salary: 50000 + Math.random() * 100000,
status: i % 3 === 0 ? 'Active' : 'Inactive'
}));
});
const Row = ({ index, style }) => {
const item = data[index];
return (
<div
style={{
...style,
display: 'grid',
gridTemplateColumns: '80px 200px 250px 150px 120px 120px',
padding: '12px',
borderBottom: '1px solid #eee',
backgroundColor: index % 2 === 0 ? '#f9f9f9' : 'white',
alignItems: 'center'
}}
>
<div>{item.id}</div>
<div>
<strong>{item.name}</strong>
<div style={{ fontSize: '12px', color: '#666' }}>{item.email}</div>
</div>
<div>
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: '#007bff',
color: 'white',
fontSize: '12px'
}}>
{item.department}
</span>
</div>
<div>${item.salary.toLocaleString()}</div>
<div>
<span style={{
padding: '4px 8px',
borderRadius: '4px',
backgroundColor: item.status === 'Active' ? '#d4edda' : '#f8d7da',
color: item.status === 'Active' ? '#155724' : '#721c24',
fontSize: '12px',
fontWeight: 'bold'
}}>
{item.status}
</span>
</div>
<div>
<button
onClick={() => console.log('Edit', item)}
style={{
padding: '4px 8px',
border: '1px solid #007bff',
backgroundColor: 'white',
color: '#007bff',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Edit
</button>
</div>
</div>
);
};
const Header = () => (
<div
style={{
display: 'grid',
gridTemplateColumns: '80px 200px 250px 150px 120px 120px',
padding: '12px',
backgroundColor: '#f5f5f5',
borderBottom: '2px solid #ddd',
fontWeight: 'bold',
position: 'sticky',
top: 0,
zIndex: 1
}}
>
<div>ID</div>
<div>Name</div>
<div>Department</div>
<div>Salary</div>
<div>Status</div>
<div>Actions</div>
</div>
);
return (
<div style={{ padding: '20px' }}>
<h2>Virtualized Data Table (5,000 items)</h2>
<div style={{ border: '1px solid #ddd', borderRadius: '4px' }}>
<Header />
<FixedSizeList
height={600}
itemCount={data.length}
itemSize={60}
width="100%"
>
{Row}
</FixedSizeList>
</div>
</div>
);
}
export default VirtualizedDataTable;
This example demonstrates:
- Virtualized list rendering for large datasets
- Grid layout for table-like appearance
- Custom row rendering with styling
- Sticky header for table structure
- Performance optimization for thousands of items
- Interactive elements (buttons) in virtualized rows
Common Issues / Troubleshooting
List not rendering: Ensure the container has a fixed
heightprop. React Window requires an explicit height to calculate the viewport.Items not displaying correctly: Make sure you're applying the
styleprop to the row element. This prop contains positioning information that's essential for virtualization.Performance issues: Use
FixedSizeListwhen all items have the same height, as it's more performant thanVariableSizeList. For variable heights, ensure youritemSizefunction is optimized.Scroll position lost: React Window maintains scroll position automatically. If you're updating data, ensure you're not recreating the entire data array on every render.
TypeScript errors: React Window includes TypeScript types. Ensure your Row component props match the expected types.
Next Steps
Now that you have a basic understanding of React Window:
- Learn about VariableSizeList for dynamic item heights
- Explore Grid component for two-dimensional data
- Implement infinite scrolling with react-window-infinite-loader
- Add item selection and interaction handling
- Learn about performance optimization techniques
- Check the official documentation: https://react-window.now.sh/
- Look for part 26 of this series for more advanced topics
Summary
You've successfully set up React Window in your React application and created your first virtualized list. The library provides excellent performance for rendering large datasets by only rendering visible items, making it perfect for building data-intensive applications.
SEO Keywords
react-window
React window virtualization
react-window tutorial
React virtualized list
react-window installation
React performance optimization
react-window example
React large list rendering
react-window setup
React scroll performance
react-window FixedSizeList
React list component
react-window VariableSizeList
React infinite scroll
react-window getting started
Top comments (0)