mediumDev Processes#90

Code review simulation

Prompt

Review this code snippet. Identify 3 issues and suggest fixes: performance, style, and potential bug.

Solution

// Issues:
// 1. Bug: missing dependency 'users' in useEffect — only runs on mount, ignores prop changes
// 2. Performance: unnecessary state — derive filtered directly instead of useEffect
// 3. Style: missing keyExtractor on FlatList — causes re-render issues
// Fixed:
function UserList({ users }) {
  const filtered = useMemo(() => users.filter(u => u.active), [users])
  return <FlatList data={filtered} keyExtractor={item => String(item.id)} renderItem={({item}) => <Text>{item.name}</Text>} />
}
Mentor's take

Code review is the merge gate that catches defects while they cost minutes instead of sprints — but only if the reviewer finds the defect that matters, ordered by severity, not by scroll position.

The blocking bug: the empty dependency array. The effect runs once on mount, so when the users prop changes, the list silently shows stale data. That's a correctness failure a snapshot test won't catch, because the first render is right.

The structural issue behind it: filtered is derived data stored as state. State-plus-effect to mirror a prop creates two sources of truth and an extra render per update. Deriving with useMemo(() => users.filter(...), [users]) deletes the state, the effect, and the bug class in one move — the fix is less code, which is what a good review pushes toward.

Third, keyExtractor: without stable keys, FlatList falls back to index identity, causing wasted re-renders and wrong item recycling when the array reorders.

A senior review also labels findings — "blocking" versus "nit" — the same discipline as separating severity from priority in a bug tracker, so the author knows what must change before merge.

Red flag: leading with formatting nits while the dependency-array bug ships. Review that filters by ease of spotting instead of severity is process theater.

Say it: "The empty deps array is the blocking bug — stale UI on prop change; the fix is deriving with useMemo instead of mirroring props into state, plus a stable keyExtractor."