Custom Hooks — Beginner React challenge.
Build a random quote generator across two files: a container that owns fetch/loading state, and a presentational child that renders quote data via props — practicing props drilling, not just async state.
Requirements
- QuoteDisplay.js must stay purely presentational: no state, no fetch logic — only props in, JSX out.
- RandomQuoteGenerator.js owns all state (quote, isLoading) and the fetchQuote calls; it passes both down to QuoteDisplay as props.
- An initial quote loads automatically on mount — no click required to see the first quote.
- New Quote button triggers a new fetch, disables itself while loading, and re-enables once resolved.
- Loading indicator and quote card are mutually exclusive, driven entirely by the isLoading prop.
- Quote text and author formatting must match exactly (quoted text, em-dash-prefixed author).
Signature
function RandomQuoteGenerator({ fetchQuote: () => Promise<{text, author}> }): JSX.Element
function QuoteDisplay({ quote: {text, author} | null, isLoading: boolean }): JSX.ElementExample
<RandomQuoteGenerator fetchQuote={fetchQuote} />
// mounts -> loading -> first quote card appears automatically
// click "New Quote" -> loading again, button disabled -> new quote replaces oldConstraints
- QuoteDisplay must not call fetchQuote or manage its own loading/quote state under any circumstance.
- isLoading must start true so the first quote load is visible without a click.
- The button must be disabled for the full duration of any in-flight fetch, including the initial one.