Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.2 KiB
2.2 KiB
title, impact, impactDescription, tags
| title | impact | impactDescription | tags |
|---|---|---|---|
| Pass Primitives to List Items for Memoization | HIGH | enables effective memo() comparison | 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):
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):
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:
// 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:
// 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.