Reference version

This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

LazyVStack

A SwiftUI LazyVStack component for lazy vertical layouts.

iOS
tvOS
Included in Expo Go
Recommended version:
~58.0.10

Expo UI LazyVStack matches the official SwiftUI LazyVStack API and arranges its children vertically.

Installation

Terminal
- npx expo install @expo/ui
- yarn expo install @expo/ui
- pnpm expo install @expo/ui
- bun expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

Usage

Basic lazy vertical stack

Put LazyVStack inside a ScrollView. Each child of LazyVStack is one row. Use the spacing and alignment props to space and align the rows.

BasicLazyVStackExample.tsx
import { Host, ScrollView, LazyVStack, Text, } from '@expo/ui/swift-ui'; export default function BasicLazyVStackExample() { return ( <Host style={{ flex: 1 }}> <ScrollView> <LazyVStack spacing={12}> <Text>Wi-Fi</Text> <Text>Bluetooth</Text> <Text>Notifications</Text> </LazyVStack> </ScrollView> </Host> ); }

Large lists

Use LazyVStack.ForEach to render rows from an array. Pass the items as data, a unique key for each item with keyExtractor, and a children function that returns the row for an item. LazyVStack.ForEach renders only the rows near the visible area and reuses them while you scroll.

LargeLazyVStackExample.tsx
import { Host, ScrollView, LazyVStack, Text, } from '@expo/ui/swift-ui'; type Contact = { id: string; name: string }; const contacts: Contact[] = Array.from( { length: 10000 }, (_, i) => ({ id: String(i), name: `Contact ${i + 1}`, }) ); function renderContact({ item }: { item: Contact }) { return <Text>{item.name}</Text>; } export default function LargeLazyVStackExample() { return ( <Host style={{ flex: 1 }}> <ScrollView> <LazyVStack spacing={12}> <LazyVStack.ForEach data={contacts} keyExtractor={contact => contact.id} estimatedItemSize={20}> {renderContact} </LazyVStack.ForEach> </LazyVStack> </ScrollView> </Host> ); }

Follow these rules when you render rows:

  • Define the children function outside the component, or wrap it in useCallback. Otherwise, the rows near the visible area render again each time the component renders.
  • A reused row keeps the local state (useState) of the item it showed before. Reset the state when the item changes, or keep the state outside the row.
  • A row that is not ready yet shows an empty placeholder. Set estimatedItemSize close to the height of your rows, in points.
  • Use overscanCount to prepare more rows above and below the visible rows.
  • To update the rows, pass a new data array. Do not change the array in place.
  • Set recycling={false} to render every row up front.

API

import { LazyVStack } from '@expo/ui/swift-ui';

Components

LazyVStackForEach

iOS
tvOS

Type: React.Element<LazyVStackForEachProps<T>>

A block of recycled rows inside LazyVStack. Only a small pool of rows around the visible range is mounted. Rows that are not ready yet show a placeholder of estimatedItemSize, or of the size last measured for that row.

Mount it as a direct child of LazyVStack.

LazyVStackForEachProps

children

iOS
tvOS
Type: (info: { index: number, item: T }) => ReactElement

Renders a row. Wrap it in useCallback, or every row re-renders on each parent render. Recycled rows are reused for other items, so their local state (useState) carries over. Reset it when the item changes, or keep the state outside the row.

data

iOS
tvOS
Type: readonly T[]

Items to display. Replace the array when updating data.

estimatedItemSize

iOS
tvOS
Optional • Type: number • Default: 64

Placeholder size in points along the stack axis, until a row is measured. Must be positive. Ignored when recycling is false.

keyExtractor

iOS
tvOS
Type: (item: T, index: number) => string

Returns a stable, unique string key for each item.

overscanCount

iOS
tvOS
Optional • Type: number • Default: 10

Extra rows to prepare on each side of the visible rows. Must be a non-negative integer. Ignored when recycling is false.

recycling

iOS
tvOS
Optional • Type: boolean • Default: true

Renders only the rows near the visible range and reuses them while scrolling. Set to false to render every row at once. Set it once; changing it remounts the rows.

LazyVStack

iOS
tvOS

Type: React.Element<LazyVStackProps>

LazyVStackProps

alignment

iOS
tvOS
Optional • Literal type: string

The horizontal alignment of children within the stack.

Acceptable values are: 'center' | 'leading' | 'trailing'

children

iOS
tvOS
Type: ReactNode

spacing

iOS
tvOS
Optional • Type: number

The spacing between children.