Skip to main content

Lists

There are two ways to render lists in Kog, and choosing correctly matters more than on the web — widget memory is the scarce resource.

Small lists: .map()

For bounded lists (menus, settings, a handful of rows), plain .map() works exactly as in React:

<View>
{items.map(item => (
<Row key={item.id} item={item} />
))}
</View>

Under the hood this compiles to a minimal keyed reconciler: when items changes, new keys mount, missing keys unmount, surviving keys move and update in place — no re-creation, and each surviving row updates only the properties that actually changed. Use stable keys; index keys draw a lint warning.

Long lists: FlatList

A thousand retained widgets will exhaust a microcontroller. FlatList renders only what's visible, using a native recycling pool: a fixed set of row widget-trees is created once, and scrolling rebinds each pooled row's data rather than creating or destroying anything.

<FlatList
data={messages}
rowHeight={56}
keyExtractor={m => m.id}
renderItem={({ item }) => (
<View style={styles.row}>
<Text style={styles.from}>{item.from}</Text>
<Text numberOfLines={1}>{item.preview}</Text>
</View>
)}
onEndReached={loadMore}
/>

Because Kog components update via fine-grained effects, recycling is exceptionally cheap: rebinding a row means writing one signal, and only the text/props that differ between the old and new item touch the display. Scrolling cost is proportional to rows entering the viewport — never to data.length.

Also supported: horizontal, numColumns, ItemSeparatorComponent, ListHeaderComponent/ListFooterComponent, onEndReachedThreshold, initialNumToRender.

Rule of thumb: if the list scrolls and can grow beyond a couple dozen rows, use FlatList. The linter warns when a large .map() sits inside a ScrollView.