JavaScript Curriculum
Conditional Rendering
easyThe coffee shop menu needs to show a loading skeleton while data fetches, an error message if it fails, an empty state if there are no items, and the actual menu when data is ready. Four states, four different UIs — all from one component.
Conditional Rendering
React components return different JSX based on state and props. There is no special directive — just JavaScript expressions inside JSX.
Five Conditional Patterns
Know which pattern to reach for in each situation:
The most common pattern. Shows A or B based on a condition. Works anywhere in JSX.
function StatusBadge({ isOnline }) { return ( <span className={isOnline ? 'badge-green' : 'badge-grey'}> {isOnline ? 'Open' : 'Closed'} </span> ) } // Works for classes too: <div className={`card ${featured ? 'featured' : ''}`}>
Loading / Error / Empty / Data — The Four States
Every component that fetches data needs to handle all four render states:
function MenuList({ isLoading, error, items }) { if (isLoading) return <Spinner /> if (error) return <ErrorMessage error={error} /> if (!items.length) return <EmptyState /> return ( <ul> {items.map(item => <MenuItem key={item.id} {...item} />)} </ul> ) }
Loading State Patterns — Skeletons vs Spinners
See loading, success, and error states in a live demo:
function Menu() { const [status, setStatus] = useState('idle') const [data, setData] = useState(null) if (status === 'loading') return <Skeleton /> if (status === 'error') return <ErrorCard onRetry={fetch} /> if (!data) return null return data.map(item => <MenuCard key={item.id} {...item} />) }
Your Challenge
Build MenuList({ isLoading, error, items }). Use early returns: if (isLoading) return <Skeleton />, if (error) return <ErrorCard />, if (!items.length) return <EmptyState />. Main render: map items to cards. Wire it to a parent that toggles these states with buttons.
Challenge
Build a MenuList component that handles four render states: loading (skeleton), error (message + retry), empty (friendly message), data (list of items). Use early returns for the first three. Never render loading and error at the same time.
Conditional Rendering
easyThe coffee shop menu needs to show a loading skeleton while data fetches, an error message if it fails, an empty state if there are no items, and the actual menu when data is ready. Four states, four different UIs — all from one component.
Conditional Rendering
React components return different JSX based on state and props. There is no special directive — just JavaScript expressions inside JSX.
Five Conditional Patterns
Know which pattern to reach for in each situation:
The most common pattern. Shows A or B based on a condition. Works anywhere in JSX.
function StatusBadge({ isOnline }) { return ( <span className={isOnline ? 'badge-green' : 'badge-grey'}> {isOnline ? 'Open' : 'Closed'} </span> ) } // Works for classes too: <div className={`card ${featured ? 'featured' : ''}`}>
Loading / Error / Empty / Data — The Four States
Every component that fetches data needs to handle all four render states:
function MenuList({ isLoading, error, items }) { if (isLoading) return <Spinner /> if (error) return <ErrorMessage error={error} /> if (!items.length) return <EmptyState /> return ( <ul> {items.map(item => <MenuItem key={item.id} {...item} />)} </ul> ) }
Loading State Patterns — Skeletons vs Spinners
See loading, success, and error states in a live demo:
function Menu() { const [status, setStatus] = useState('idle') const [data, setData] = useState(null) if (status === 'loading') return <Skeleton /> if (status === 'error') return <ErrorCard onRetry={fetch} /> if (!data) return null return data.map(item => <MenuCard key={item.id} {...item} />) }
Your Challenge
Build MenuList({ isLoading, error, items }). Use early returns: if (isLoading) return <Skeleton />, if (error) return <ErrorCard />, if (!items.length) return <EmptyState />. Main render: map items to cards. Wire it to a parent that toggles these states with buttons.
Challenge
Build a MenuList component that handles four render states: loading (skeleton), error (message + retry), empty (friendly message), data (list of items). Use early returns for the first three. Never render loading and error at the same time.