React Cheatsheet
Lists and Keys
Use this React reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Rendering Lists with map
// Basic list rendering function NameList({ names }) { return ( <ul> {names.map((name, index) => ( <li key={index}>{name}</li> ))} </ul> ); } // Objects — use stable ID as key function UserList({ users }) { return ( <ul> {users.map(user => ( <li key={user.id}> <strong>{user.name}</strong> — {user.email} </li> ))} </ul> ); }
Keys
A key is a special string attribute that helps React identify which items have changed, been added, or removed.
// key must be: // 1. Unique among siblings (not globally) // 2. Stable across renders (not random) // 3. Predictable from the data // GOOD — stable ID from data {items.map(item => <Item key={item.id} data={item} />)} // ACCEPTABLE — stable string key {Object.entries(config).map(([key, val]) => ( <ConfigRow key={key} name={key} value={val} /> ))} // BAD — index as key when list can reorder/filter/insert {items.map((item, i) => <Item key={i} />)} // causes bugs with state // OK to use index only when: // - list is static and never reorders // - items have no state or controlled inputs {staticLabels.map((label, i) => <span key={i}>{label}</span>)} // BAD — random key causes remount every render {items.map(item => <Item key={Math.random()} />)}
Key Rules and Gotchas
// Keys must be unique among SIBLINGS only, not across the whole tree function App() { return ( <> <ul> {listA.map(i => <li key={i.id}>{i.name}</li>)} {/* keys scoped here */} </ul> <ul> {listB.map(i => <li key={i.id}>{i.name}</li>)} {/* separate scope */} </ul> </> ); } // Key is NOT accessible as a prop — use a separate id prop if needed function Item({ id, data }) { // key={id} above; pass id separately // props.key → undefined } // Keys on Fragments import { Fragment } from 'react'; {items.map(item => ( <Fragment key={item.id}> <dt>{item.term}</dt> <dd>{item.def}</dd> </Fragment> ))} // Shorthand <> </> does NOT accept key — must use <Fragment>
List Transformations
// filter then map {users .filter(u => u.active) .map(u => <UserCard key={u.id} user={u} />) } // sort then map (sort mutates — copy first) {[...items] .sort((a, b) => a.name.localeCompare(b.name)) .map(item => <li key={item.id}>{item.name}</li>) } // flatMap {sections .flatMap(section => section.items) .map(item => <li key={item.id}>{item.title}</li>) } // reduce to group, then render groups const byCategory = items.reduce((acc, item) => { (acc[item.category] ??= []).push(item); return acc; }, {}); {Object.entries(byCategory).map(([cat, items]) => ( <div key={cat}> <h3>{cat}</h3> <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul> </div> ))}
Nested Lists
function Tree({ nodes }) { return ( <ul> {nodes.map(node => ( <li key={node.id}> {node.label} {node.children?.length > 0 && <Tree nodes={node.children} />} </li> ))} </ul> ); }
Keyed Fragments and Tables
// Table rows function Table({ rows }) { return ( <table> <tbody> {rows.map(row => ( <tr key={row.id}> {row.cells.map((cell, i) => <td key={i}>{cell}</td>)} </tr> ))} </tbody> </table> ); } // Definition list with keyed fragments function Glossary({ terms }) { return ( <dl> {terms.map(({ id, word, def }) => ( <Fragment key={id}> <dt>{word}</dt> <dd>{def}</dd> </Fragment> ))} </dl> ); }
Empty States
function ItemList({ items }) { if (!items.length) return <p className="muted">No items found.</p>; return <ul>{items.map(i => <li key={i.id}>{i.name}</li>)}</ul>; } // Inline empty state {items.length === 0 ? <p>Nothing here yet.</p> : <ul>{items.map(...)}</ul> }
Virtualization (Large Lists)
For thousands of items, virtualize to only render visible rows.
// react-window import { FixedSizeList } from 'react-window'; function VirtualList({ items }) { const Row = ({ index, style }) => ( <div style={style}>{items[index].name}</div> ); return ( <FixedSizeList height={600} itemCount={items.length} itemSize={48} width="100%" > {Row} </FixedSizeList> ); } // react-virtual (TanStack Virtual) — headless alternative import { useVirtualizer } from '@tanstack/react-virtual';
Generating Unique Keys
// When data has no ID, generate one at creation time (not in render) import { useId } from 'react'; // for DOM ids only import { nanoid } from 'nanoid'; // npm install nanoid // Add ID when adding to state — NOT inside map() const addItem = (text) => setItems(prev => [...prev, { id: nanoid(), text }]); // crypto.randomUUID() — native, available in modern browsers/Node const id = crypto.randomUUID();
Performance Tips
// 1. Keys enable minimal DOM updates — correct keys > everything else // 2. Memoize expensive list items const MemoItem = React.memo(Item); {items.map(i => <MemoItem key={i.id} data={i} />)} // 3. Stable callbacks to memoized children (use useCallback) const handleDelete = useCallback((id) => { setItems(prev => prev.filter(i => i.id !== id)); }, []); // 4. Avoid inline arrow functions in map when children are memoized // BAD: <Item key={i.id} onDelete={() => deleteItem(i.id)} /> — new fn each render // GOOD: pass stable handler + id; let Item call it