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
Pass Primitives to List Items for Memoization
impact
HIGH
impactDescription
enables effective memo() comparison
tags
lists, performance, memo, primitives

Pass Primitives to List Items for Memoization

When possible, pass only primitive values (strings, numbers, booleans) as props to list item components. Primitives enable shallow comparison in memo() to work correctly, skipping re-renders when values haven't changed.

Incorrect (object prop requires deep comparison):

tsx
type User = { id: string; name: string; email: string; avatar: string }
const UserRow = memo(function UserRow({ user }: { user: User }) {  // memo() compares user by reference, not value  // If parent creates new user object, this re-renders even if data is same  return <Text>{user.name}</Text>})
renderItem={({ item }) => <UserRow user={item} />}

This can still be optimized, but it is harder to memoize properly.

Correct (primitive props enable shallow comparison):

tsx
const UserRow = memo(function UserRow({  id,  name,  email,}: {  id: string  name: string  email: string}) {  // memo() compares each primitive directly  // Re-renders only if id, name, or email actually changed  return <Text>{name}</Text>})
renderItem={({ item }) => (  <UserRow id={item.id} name={item.name} email={item.email} />)}

Pass only what you need:

tsx
// Incorrect: passing entire item when you only need name<UserRow user={item} />
// Correct: pass only the fields the component uses<UserRow name={item.name} avatarUrl={item.avatar} />

For callbacks, hoist or use item ID:

tsx
// Incorrect: inline function creates new reference<UserRow name={item.name} onPress={() => handlePress(item.id)} />
// Correct: pass ID, handle in child<UserRow id={item.id} name={item.name} />
const UserRow = memo(function UserRow({ id, name }: Props) {  const handlePress = useCallback(() => {    // use id here  }, [id])  return <Pressable onPress={handlePress}><Text>{name}</Text></Pressable>})

Primitive props make memoization predictable and effective.

Note: If you have the React Compiler enabled, you do not need to use memo() or useCallback(), but the object references still apply.