Episode 2 — React Frontend Architecture NextJS / 2.2 — React Components and Props

2.2 — React Components & Props: Quick Revision

Compact cheat sheet. Print-friendly. One section per sub-topic.


How to Use This Material

  1. Quick refresher — scan before interviews or coding sessions
  2. Spot check — if something looks unfamiliar, go back to the full sub-topic
  3. Flashcards — cover the right column in tables and test yourself
  4. Print it — keep next to your monitor during coding

2.2.a — Functional Components

ConceptKey Point
DefinitionA function that returns JSX
NamingPascalCase, starts with uppercase
Return valuesJSX, null, string, number, array, fragment, boolean (renders nothing)
Declaration vs ArrowBoth work. Arrows can't be hoisted. Team convention decides
Default exportexport default function X() — one per file
Named exportexport function X() — multiple per file, explicit imports
Barrel fileindex.js that re-exports: export { Button } from './Button'
// Minimum viable component
function Hello() {
  return <h1>Hello</h1>;
}

2.2.b — Understanding Props

ConceptKey Point
What are propsInputs from parent, like function arguments
Data flowOne-way: parent → child only
ImmutabilityNEVER mutate props. Create copies
Destructuringfunction Card({ title, size = "md" })
ChildrenSpecial prop: content between <Tag>...</Tag>
Spread{...props} forwards all properties
CallbacksFunctions as props for child → parent communication
Default valuesUse default parameters, NOT defaultProps
TypeScriptinterface Props { name: string; age?: number }
// Destructure + defaults + children
function Card({ title, variant = "outlined", children }) {
  return <div className={`card card-${variant}`}><h2>{title}</h2>{children}</div>;
}

Props vs State:

PropsState
OwnerParentSelf
Mutable?NoYes (via setter)
PurposeConfigurationInteractive data

2.2.c — Dynamic Rendering

PatternSyntaxUse When
Interpolation{value}Display data
AND operator{condition && <X />}Show/hide one thing
Ternary{cond ? <A /> : <B />}Choose between two
Early returnif (loading) return <Spinner />Handle edge cases first
Object lookupconst map = { a: <A/> }; map[key]Multiple variants (>3)

Gotcha: {0 && <X />} renders 0. Fix: {count > 0 && <X />}

// Number formatting
new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(29.99)
// → "$29.99"

2.2.d — Rendering Lists

// The pipeline
data
  .filter(item => item.active)       // Remove unwanted
  .sort((a, b) => a.name.localeCompare(b.name))  // Order
  .slice(0, 10)                      // Paginate
  .map(item => <Card key={item.id} item={item} />)  // Render
RuleDetail
Use map()Not forEach() (doesn't return)
Always add keyOn outermost element in map()
Never mutate[...arr].sort(), not arr.sort()
Handle emptyShow <EmptyState /> when length === 0
Handle loadingShow skeleton, not blank
Extract itemsWhen item JSX > 10 lines → own component

2.2.e — Keys in React

RuleDetail
PurposeTrack item identity across renders
UniqueAmong siblings (different lists can reuse keys)
StableSame item = same key every render
Best keysDatabase ID, UUID, slug, email
Bad keysMath.random(), Date.now(), index (when list changes)
Index OK whenStatic list, no reorder, no state in items

The index-as-key bug:

Check item 0 → delete item 0 → item 1 slides to position 0 → inherits checked state

Fix: key={item.id} instead of key={index}

Key tricks:

// Force re-mount (reset state)
<EditForm key={selectedUserId} user={user} />

// Keys on fragments
<React.Fragment key={item.id}><dt/><dd/></React.Fragment>

// Composite keys
key={`${day}-${room}-${time}`}

Key is NOT a propprops.key is undefined inside the component.


2.2.f — Reusable Card Component

Compound component pattern:

<Card variant="elevated">
  <Card.Image src="..." alt="..." />
  <Card.Header title="..." subtitle="..." />
  <Card.Body>Content</Card.Body>
  <Card.Footer><Button>Action</Button></Card.Footer>
</Card>
VariantStyle
outlinedBorder, white bg, no shadow
elevatedNo border, white bg, box-shadow
filledNo border, gray bg, no shadow

Clickable card essentials:

  • cursor: pointer
  • role="button" + tabIndex={0}
  • Handle Enter and Space keydown
  • Hover: translateY(-2px) + shadow increase
  • Use <a> if it navigates, <div> + onClick if it triggers action

Card grid:

display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;

Core Formulas

Component = f(props) → JSX
Props flow: Parent → Child (one-way)
Callback flow: Child → Parent (via function props)
Re-render triggers: props change OR state change
Key identity: same key = same component instance

Decision Quick-Reference

SituationDecision
Need to share data downUse props
Child needs to tell parentPass callback as prop
Data goes through 4+ levelsUse Context (covered 2.13)
Multiple visual variantsUse variant prop
Complex component with sectionsCompound component pattern
List with changing itemsUse stable unique keys
Form with validationControlled inputs
Data-dependent UIDynamic rendering with &&/ternary

Quick revision for 2.2 — React Components & Props

For deep dives, see the individual sub-topic files (2.2.a through 2.2.f)