Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build performant React Native and Expo apps with best practices for lists, animations, and navigation
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/list-performance-item-expensive.md
1---2title: Keep List Items Lightweight3impact: HIGH4impactDescription: reduces render time for visible items during scroll5tags: lists, performance, virtualization, hooks6---78## Keep List Items Lightweight910List items should be as inexpensive as possible to render. Minimize hooks, avoid11queries, and limit React Context access. Virtualized lists render many items12during scroll—expensive items cause jank.1314**Incorrect (heavy list item):**1516```tsx17function ProductRow({ id }: { id: string }) {18// Bad: query inside list item19const { data: product } = useQuery(['product', id], () => fetchProduct(id))20// Bad: multiple context accesses21const theme = useContext(ThemeContext)22const user = useContext(UserContext)23const cart = useContext(CartContext)24// Bad: expensive computation25const recommendations = useMemo(26() => computeRecommendations(product),27[product]28)2930return <View>{/* ... */}</View>31}32```3334**Correct (lightweight list item):**3536```tsx37function ProductRow({ name, price, imageUrl }: Props) {38// Good: receives only primitives, minimal hooks39return (40<View>41<Image source={{ uri: imageUrl }} />42<Text>{name}</Text>43<Text>{price}</Text>44</View>45)46}47```4849**Move data fetching to parent:**5051```tsx52// Parent fetches all data once53function ProductList() {54const { data: products } = useQuery(['products'], fetchProducts)5556return (57<LegendList58data={products}59renderItem={({ item }) => (60<ProductRow name={item.name} price={item.price} imageUrl={item.image} />61)}62/>63)64}65```6667**For shared values, use Zustand selectors instead of Context:**6869```tsx70// Incorrect: Context causes re-render when any cart value changes71function ProductRow({ id, name }: Props) {72const { items } = useContext(CartContext)73const inCart = items.includes(id)74// ...75}7677// Correct: Zustand selector only re-renders when this specific value changes78function ProductRow({ id, name }: Props) {79// use Set.has (created once at the root) instead of Array.includes()80const inCart = useCartStore((s) => s.items.has(id))81// ...82}83```8485**Guidelines for list items:**8687- No queries or data fetching88- No expensive computations (move to parent or memoize at parent level)89- Prefer Zustand selectors over React Context90- Minimize useState/useEffect hooks91- Pass pre-computed values as props9293The goal: list items should be simple rendering functions that take props and94return JSX.95