Passing asynchronously acquired data to child props
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
In React, asynchronous data usually arrives after the first render, which means child components often receive null, an empty array, or a loading flag before the real payload exists. The clean solution is to let the parent own the fetch lifecycle, then pass stable props that describe loading, error, and data explicitly.
Fetch in the Parent, Render in the Child
The parent component is normally responsible for requesting data, storing it in state, and deciding when the child should render. That keeps the child focused on presentation.
This pattern does two useful things. First, the child gets a predictable contract. Second, the cleanup flag prevents state updates after unmount, which is a common source of warnings and race conditions.
Design Child Props Around States, Not Just Data
Instead of assuming the child always receives a full object, define props that represent all realistic states.
That is more robust than passing user! or assuming the child can immediately dereference fields like user.name.
Passing Collections to Child Components
The same principle applies to arrays. Start with an empty array if that makes the child logic simpler, or keep null when you need to distinguish "not loaded yet" from "loaded but empty".
An empty array is often the easiest default because methods like .map() are safe immediately.
When to Lift Fetching Higher
If several children need the same asynchronous result, fetch once in a shared parent and pass the derived pieces down. That avoids duplicate requests and inconsistent loading behavior. If the tree becomes deep, React context or a data library such as TanStack Query can make the flow cleaner, but the principle remains the same: keep ownership of asynchronous state close to where the request is coordinated.
Common Pitfalls
The most common bug is rendering child code that assumes data exists before the request completes. That leads to errors such as "Cannot read properties of null". Use loading guards or optional chaining where appropriate, but prefer explicit render branches over hiding missing state everywhere.
Another problem is starting a fetch in the parent and separately starting a second fetch in the child for the same data. That duplicates network work and makes state harder to reason about. Decide which component owns the request.
Race conditions are also easy to introduce when props change quickly. If a child depends on data fetched from an id passed by the parent, cancel stale requests or ignore stale responses so older data does not overwrite newer state.
Summary
- Fetch asynchronous data in the parent when that parent owns the view state.
- Pass
loading,error, anddataas explicit props instead of assuming data is immediately available. - Use
nullor an empty array intentionally based on what state distinctions you need. - Guard child rendering so it handles not-yet-loaded data safely.
- Lift shared fetching higher in the tree to avoid duplicated requests and inconsistent state.
Related reading
- passing multiple arguments to promise resolution within setTimeout
- Passing object by reference to stdthread in C11
- passing parameters to Node.js async waterfall
- Passing value into next Promises argument
- Passing HTML to template using Flask/Jinja2
- Perform actions as promises get fulfilled using Promise.all
- Pattern for updating slave SQL Server 2008 databases from a master whilst minimising disruption
- Patterns for Multithreaded Network Server in C
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.