Props as Inputs
Two LessonCard elements can use the same component function and display different lessons. Props carry the values supplied by each element into its component call.
<LessonCard title="Props as Inputs" minutes={14} />
<LessonCard title="Children as Composition" minutes={12} />React creates two element descriptions with the same component type and different props. During rendering, React calls LessonCard for each occurrence and passes one props object.
first element -> { title, minutes }
second element -> { title, minutes }The function code is shared. Each rendered occurrence receives its own input object.
Receive One Object
Start without destructuring.
function LessonCard(props) {
return (
<article>
<h2>{props.title}</h2>
<p>{props.minutes} min</p>
</article>
);
}React calls the function with one argument. That argument is the props object for the current element.
This signature does not receive one positional argument per JSX attribute.
function LessonCard(title, minutes) {
// wrong model
}title would receive the whole props object. minutes would not receive the second JSX prop.
A function component receives one props object. JSX prop names become properties on that object.
The object can be inspected temporarily.
function LessonCard(props) {
console.log(props);
return <h2>{props.title}</h2>;
}Development Strict Mode can call the component again, so the log can appear more than once. Remove the log after observing the object.
The Parent Supplies the Props
LessonList creates the child element.
function LessonList() {
return (
<LessonCard
title="Props as Inputs"
minutes={14}
/>
);
}For this element, LessonList is the parent component and LessonCard is the child component. The parent chooses the values because it creates the element.
The child reads those values while calculating its output.
function LessonCard(props) {
return <h2>{props.title}</h2>;
}This direction is often described as data flowing down the component tree. A parent passes props to a child. If the child needs to report an event upward, the parent can supply a callback prop.
Quoted Props and Braced Props
A quoted JSX prop value is a string.
<LessonCard title="Props as Inputs" />Braces evaluate a JavaScript expression.
<LessonCard minutes={14} />Without braces, the number would be text.
<LessonCard minutes="14" />Both can display 14, but their JavaScript types differ. Arithmetic, sorting, and TypeScript contracts depend on the correct type.
Pass a variable through braces.
const lessonMinutes = 14;
<LessonCard minutes={lessonMinutes} />Pass an object the same way.
const lesson = {
title: "Props as Inputs",
minutes: 14,
};
<LessonCard lesson={lesson} />Props can carry strings, numbers, booleans, objects, arrays, functions, React nodes, and other JavaScript values supported by the current environment. What the child does with a value determines whether it can be rendered, called, or passed onward.
Destructure Named Properties
Parameter destructuring creates local bindings from the props object.
function LessonCard({ title, minutes }) {
return (
<article>
<h2>{title}</h2>
<p>{minutes} min</p>
</article>
);
}React still passes one object. JavaScript applies the destructuring pattern before the function body uses the bindings.
The property names must match the JSX prop names.
<LessonCard minutes={14} />function LessonCard({ duration }) {
return <p>{duration} min</p>;
}duration is undefined because the props object has minutes, not duration.
Rename a property explicitly when the local name should differ.
function LessonCard({ minutes: duration }) {
return <p>{duration} min</p>;
}The public prop remains named minutes. Only the local binding is duration.
Missing Props Produce undefined
Render the component without minutes.
<LessonCard title="Props as Inputs" />The object has no minutes property, so reading it produces undefined.
function LessonCard({ title, minutes }) {
return <p>{title}, {minutes} min</p>;
}React renders no text for the undefined expression. The page can display Props as Inputs, min without throwing an exception.
Choose a defined omitted behavior. A default can supply a normal value.
function LessonCard({ title, minutes = 10 }) {
return <p>{title}, {minutes} min</p>;
}The default applies when the prop is omitted or explicitly undefined.
<LessonCard title="Props" />
<LessonCard title="Props" minutes={undefined} />It does not apply to null.
<LessonCard title="Props" minutes={null} />null is an explicit supplied value. React renders no text for it in this position.
A parameter default handles undefined. It does not validate every value a caller can supply.
TypeScript can report static caller mismatches. Values from a server or storage still require runtime validation.
Boolean Shorthand Supplies true
A JSX prop written without a value receives true.
<LessonCard featured />This has the same prop value as the explicit form.
<LessonCard featured={true} />Omitting the prop gives the child undefined when it reads featured.
<LessonCard />Supply false explicitly when the prop needs to be present with a false value.
<LessonCard featured={false} />Use boolean names that read as conditions, such as featured, complete, disabled, and showDetails.
Props Are Read-Only Inputs
A component must not assign to its props object.
function LessonCard(props) {
props.title = props.title.toUpperCase();
return <h2>{props.title}</h2>;
}The parent supplied the value. The child should calculate another local value.
function LessonCard({ title }) {
const displayTitle = title.toUpperCase();
return <h2>{displayTitle}</h2>;
}The local binding exists only for this render. The supplied prop remains unchanged.
React's render model depends on components calculating from their current inputs without changing those inputs. A later parent render can supply another value through another element description.
<LessonCard title="Children as Composition" />React calls the child with the next props object during that render. The child does not write into the old object to request the update.
The parent supplies props when it creates the element. Treat those values as read-only during rendering.
Nested Objects Remain Shared References
Object props require another level of care.
const lesson = {
title: "Props as Inputs",
complete: false,
};
<LessonCard lesson={lesson} />The props object contains a reference to lesson. React does not deep-copy that object.
This component mutates the parent's data.
function LessonCard({ lesson }) {
lesson.complete = true;
return <h2>{lesson.title}</h2>;
}Any code holding the same object can observe the changed property. The mutation also occurred during render.
Read the object and derive output.
function LessonCard({ lesson }) {
const label = lesson.complete ? "Complete" : "Not started";
return <p>{lesson.title}, {label}</p>;
}When completion changes, the parent supplies a new data value and the child renders from that value.
Special Props Do Not Reach the Component Normally
React uses key for list identity and does not pass it as an ordinary prop.
<LessonCard key={lesson.id} lesson={lesson} />LessonCard cannot read props.key. Pass another prop if it needs the ID.
<LessonCard
key={lesson.id}
lessonId={lesson.id}
lesson={lesson}
/>React 19 makes ref available as a prop to function components, while React handles its attachment behavior according to the element and component. Add a ref only when code needs imperative access to a host node or another supported ref target.
Do Not Copy Props into State by Default
Copying an initial prop into state disconnects future prop changes from the displayed value.
function LessonCard({ title }) {
const [localTitle] = useState(title);
return <h2>{localTitle}</h2>;
}The initial state uses the first title. A later parent prop does not automatically replace localTitle. The card can display old text while the parent supplies new text.
If the component only needs to display or calculate from a prop, read the prop directly.
function LessonCard({ title }) {
return <h2>{title}</h2>;
}Local state is appropriate when the value can change independently inside that component instance.
Build a Reusable Lesson Card
Define the card in its own module.
export default function LessonCard({ title, minutes, complete = false }) {
const status = complete ? "Complete" : "Not started";
return (
<article>
<h2>{title}</h2>
<p>{minutes} min</p>
<p>{status}</p>
</article>
);
}Render two occurrences from App.
<LessonCard
title="Props as Inputs"
minutes={14}
complete
/><LessonCard
title="Children as Composition"
minutes={12}
/>The function code remains unchanged. Each element supplies the values for one card occurrence.
Check the Prop Path
Trace each prop from the parent expression to the component that reads it.
parent creates a component element
JSX records supplied prop values
React calls the component with one props object
the component reads without mutating
the returned UI follows those inputs
a later parent render can supply another props objectSource Notes
- React documentation, Passing Props to a Component
- React documentation, Keeping Components Pure
- React documentation, Special Props Warning
- React 19 upgrade guide,
refas a prop