列表
一个虚拟化的垂直行容器,与可点击的 ListItem 原始组件配对使用。
For the complete documentation index, see llms.txt. Use this file to discover all available pages.
List 提供了一个虚拟化的垂直行容器,通常由 ListItem 子元素填充。它提供平台原生的外观(分隔线、内边距样式、下拉刷新)。ListItem 是一个可点击的行,具有 leading/trailing/supportingText 插槽。
安装
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
用法
基本列表
import { useState } from 'react'; import { Host, List, ListItem, Text } from '@expo/ui'; const ITEMS = [ { id: 1, name: '牛油果吐司' }, { id: 2, name: '奶油奶酪百吉饼' }, { id: 3, name: '卡布奇诺' }, ]; export default function ListExample() { const [selected, setSelected] = useState<string | null>(null); return ( <Host style={{ flex: 1 }}> <List> {ITEMS.map(item => ( <ListItem key={item.id} onPress={() => setSelected(item.name)}> {item.name} </ListItem> ))} </List> {selected != null && <Text>已选择:{selected}</Text>} </Host> ); }
带插槽的行
ListItem 在常见场景下接受 leading、trailing 和 supportingText 这几个简写属性。当需要更丰富的内容时,可为其中任意项传入 ReactNode。
import { Host, Icon, List, ListItem } from '@expo/ui'; const CHEVRON = Icon.select({ ios: 'chevron.right', android: require('@expo/material-symbols/chevron_right.xml'), }); export default function ListItemSlotsExample() { return ( <Host style={{ flex: 1 }}> <List> <ListItem onPress={() => {}} trailing={<Icon name={CHEVRON} size={14} color="gray" />} supportingText="标题下方的副标题行"> 个人资料 </ListItem> <ListItem onPress={() => {}} trailing={<Icon name={CHEVRON} size={14} color="gray" />}> 设置 </ListItem> </List> </Host> ); }
复合插槽子元素
如需对插槽内容进行完全控制,请使用复合 API:<ListItem.Leading>、<ListItem.Trailing> 和 <ListItem.Supporting>。任何未被插槽包裹的内容都会成为标题。
import { Host, Icon, List, ListItem, Row, Text } from '@expo/ui'; export default function ListItemCompoundExample() { return ( <Host style={{ flex: 1 }}> <List> <ListItem onPress={() => {}}> <ListItem.Leading> <Icon name="star.fill" size={20} color="#FFD60A" /> </ListItem.Leading> <Row spacing={0}> <Text textStyle={{ color: 'gray' }}>{`#42: `}</Text> <Text>复合标题</Text> </Row> <ListItem.Supporting>更丰富的插槽内容</ListItem.Supporting> </ListItem> </List> </Host> ); }
下拉刷新
传入一个 async 的 onRefresh 处理函数。平台原生的刷新指示器会一直显示,直到返回的 promise 结束(resolve 或 reject)。
import { useState } from 'react'; import { Host, List, ListItem } from '@expo/ui'; export default function ListRefreshExample() { const [items, setItems] = useState([1, 2, 3]); const handleRefresh = async () => { await new Promise(resolve => setTimeout(resolve, 1500)); setItems(prev => [Math.max(...prev) + 1, ...prev]); }; return ( <Host style={{ flex: 1 }}> <List onRefresh={handleRefresh}> {items.map(id => ( <ListItem key={id}>{`项目 #${id}`}</ListItem> ))} </List> </Host> ); }
Web 端尚未实现下拉刷新。该处理函数会被接受以保持 API 一致性,但指示器仅会出现在 Android 和 iOS 上。
API
import { List, ListItem } from '@expo/ui';
Component
Type: React.Element<ListProps>
A vertical container of rows.
Typically populated with ListItem children.
() => Promise<void>Optional pull-to-refresh handler. When provided, the list shows the platform-native refresh affordance. The returned promise drives the indicator's visibility.
Components
Type: React.Element<ListItemProps>
A tappable row in a list.
Composes with List.
Pass row content via the leading / trailing / supportingText shorthand props or the compound <ListItem.Leading> / <ListItem.Trailing> / <ListItem.Supporting> slot children.
Props for the ListItem component.
A tappable row in a list.
ReactNodeHeadline content of the row. The remaining (non-slot) children are rendered in the headline area.
ReactNodeShorthand for the leading slot.
Overridden by <ListItem.Leading> if both are provided.
() => voidTap handler. Activates over the entire row rectangle, including the empty gap between leading/headline/trailing.
ReactNodeShorthand for the supporting (sub-)text slot.
Strings are rendered with platform-appropriate secondary styling; pass a ReactNode for richer content.
Overridden by <ListItem.Supporting> if both are provided.
stringIdentifier used to locate the component in end-to-end tests.
ReactNodeShorthand for the trailing slot.
Overridden by <ListItem.Trailing> if both are provided.