Deft
Ask AI

Search

Search skills, authors and topics

vercel-labs / agent-skills

vercel-react-native-skills

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

Install

npx skills add https://github.com/vercel-labs/agent-skills --skill vercel-react-native-skills
title
Keep List Items Lightweight
impact
HIGH
impactDescription
reduces render time for visible items during scroll
tags
lists, performance, virtualization, hooks

Keep List Items Lightweight

List items should be as inexpensive as possible to render. Minimize hooks, avoid queries, and limit React Context access. Virtualized lists render many items during scroll—expensive items cause jank.

Incorrect (heavy list item):

tsx
function ProductRow({ id }: { id: string }) {  // Bad: query inside list item  const { data: product } = useQuery(['product', id], () => fetchProduct(id))  // Bad: multiple context accesses  const theme = useContext(ThemeContext)  const user = useContext(UserContext)  const cart = useContext(CartContext)  // Bad: expensive computation  const recommendations = useMemo(    () => computeRecommendations(product),    [product]  )
  return <View>{/* ... */}</View>}

Correct (lightweight list item):

tsx
function ProductRow({ name, price, imageUrl }: Props) {  // Good: receives only primitives, minimal hooks  return (    <View>      <Image source={{ uri: imageUrl }} />      <Text>{name}</Text>      <Text>{price}</Text>    </View>  )}

Move data fetching to parent:

tsx
// Parent fetches all data oncefunction ProductList() {  const { data: products } = useQuery(['products'], fetchProducts)
  return (    <LegendList      data={products}      renderItem={({ item }) => (        <ProductRow name={item.name} price={item.price} imageUrl={item.image} />      )}    />  )}

For shared values, use Zustand selectors instead of Context:

tsx
// Incorrect: Context causes re-render when any cart value changesfunction ProductRow({ id, name }: Props) {  const { items } = useContext(CartContext)  const inCart = items.includes(id)  // ...}
// Correct: Zustand selector only re-renders when this specific value changesfunction ProductRow({ id, name }: Props) {  // use Set.has (created once at the root) instead of Array.includes()  const inCart = useCartStore((s) => s.items.has(id))  // ...}

Guidelines for list items:

  • No queries or data fetching
  • No expensive computations (move to parent or memoize at parent level)
  • Prefer Zustand selectors over React Context
  • Minimize useState/useEffect hooks
  • Pass pre-computed values as props

The goal: list items should be simple rendering functions that take props and return JSX.