In our previous lesson, you successfully created your first functional components. You learned that components are reusable UI building blocks, much like custom HTML tags, and saw how to embed JavaScript expressions within them. However, the components we built were static; the Welcome component, for instance, could only display the specific text hardcoded within it. This limits reusability, which is the cornerstone of the component library you aim to build.
This lesson tackles that exact problem. We will explore props, the mechanism React uses to make components dynamic and configurable. You will learn how to pass data from a parent component down to a child, allowing you to reuse a single component definition (like a Button or UserProfile) to render different content each time. This concept is fundamental to moving from static mockups to interactive, data-driven applications.
What Are Props?
In React, data flows in one direction: from parent components down to child components. This mechanism for passing data is called props (short for "properties"). You can think of props as the configuration options for your components.

Given your background in JavaScript and C++, the most intuitive way to understand props is to think of them as arguments to a function. In the last lesson, we established that a React component is essentially a JavaScript function that returns JSX. Following that logic, props are the arguments you pass to that function to change what it returns.
The following video does an excellent job of drawing this parallel, starting with a pure JavaScript function and then translating the concept directly to a React component.
This video, "React Props are Easy" by Sam Meech-Ward, provides a clear and practical analogy between function parameters and React props, which will connect well with your existing programming knowledge.
Please watch these key segments: The analogy: This part demonstrates how you'd use parameters to make a regular JavaScript function reusable and then applies the exact same thinking to a React component. The syntax: Here, you'll see how to pass these "arguments" in JSX using a syntax that resembles HTML attributes. Receiving props: This section explains how the props you pass arrive in the child component as a single object.
Passing and Reading Props
As you saw in the video, the process involves two main steps. The official React documentation provides a concise guide to this workflow.
This reading from the React team breaks down the essential two-step process of passing and reading props with clear code examples.
Focus on the sections Step 1 and Step 2. This will solidify the syntax for both the parent (passing) and the child (reading).
To summarize the process:
-
In the Parent Component: You pass props by adding attributes to the JSX tag of the child component, just like you would with HTML. The value can be a string in quotes or a dynamic JavaScript value (like a variable, number, or object) in curly braces
{}.// In ParentComponent.jsx <ChildComponent name="Sai" age={20} details={{ city: "Hyderabad" }} /> -
In the Child Component: The component function receives a single argument: an object containing all the props. By convention, this object is named
props. You can then access the values using dot notation (e.g.,props.name).// In ChildComponent.jsx const ChildComponent = (props) => { return ( <p> {props.name} is {props.age} years old. </p> ); };
Prop Destructuring
While props.name works perfectly fine, you'll find that most modern React code uses JavaScript's destructuring assignment for a cleaner and more readable approach. You can destructure the props object right in the function's parameter list. This creates local variables for each prop, so you don't have to type props. everywhere.
This is the same concept you're familiar with from modern JavaScript.
// Instead of this:
const ChildComponent = (props) => {
return (
<p>
{props.name} is {props.age} years old.
</p>
);
};
// You can write this:
const ChildComponent = ({ name, age }) => {
return (
<p>
{name} is {age} years old.
</p>
);
};
Let's Code: Making Your Component Dynamic
Let's apply this to the Welcome component you built in the previous lesson.
-
Open
src/App.jsx. Modify the<Welcome />component to pass anameprop. You can use your own name or any other.// src/App.jsx import Welcome from './components/Welcome'; function App() { const userName = "Sai"; return ( <> <h1>My App</h1> {/* Pass the userName variable as a prop named 'name' */} <Welcome name={userName} /> {/* You can reuse it with different data */} <Welcome name="React Developer" /> </> ); } export default App; -
Open
src/components/Welcome.jsx. Modify it to accept and use thenameprop. Use destructuring for this.// src/components/Welcome.jsx // Use destructuring to get the 'name' prop const Welcome = ({ name }) => { return ( <div> {/* Use the prop value instead of a hardcoded string */} <h2>Welcome to Your Component Library, {name}!</h2> <p>The current year is {new Date().getFullYear()}.</p> </div> ); }; export default Welcome;
Run your development server (npm run dev). You should now see two Welcome components, each displaying the different name passed to it. You've just made your first truly reusable component!
Important Prop Concepts
As you build your component library, you'll encounter a few other important concepts related to props.
1. Default Props
What happens if a parent component forgets to pass a prop? The value will be undefined, which might cause errors or unexpected UI. You can specify default values for props directly in the destructuring assignment.
This section of the React docs shows the modern, clean syntax for setting default values for props.
Read the short section Specifying a default value. This is a simple but powerful technique for making your components more robust.
For example, you could ensure your Welcome component always has a name to display:const Welcome = ({ name = "Guest" }) => { ... };
2. The children Prop
Some components are designed to be generic "wrappers" or "containers," like a Card or a Panel. You don't know ahead of time what content will go inside them. For this, React has a special prop: children. Any JSX you place between a component's opening and closing tags is automatically passed to that component in the children prop.
This concept is vital for creating flexible layout and wrapper components, which are essential in any component library.
Please read the section Passing JSX as children. Pay attention to how the Card component is defined to accept and render its children.
Here's a quick example. Let's create a simple Card component.
// src/components/Card.jsx
const Card = ({ children }) => {
const cardStyle = {
padding: '20px',
margin: '20px',
border: '1px solid #ddd',
borderRadius: '8px',
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
};
return (
<div style={cardStyle}>
{children}
</div>
);
};
export default Card;
Now you can use it in App.jsx to wrap any content you like:
// src/App.jsx
import Card from './components/Card';
import Welcome from './components/Welcome';
function App() {
return (
<Card>
<Welcome name="Sai" />
</Card>
);
}
3. Props are Read-Only
This is one of the most important rules in React. A component must never change its own props. Props are immutable. When a component needs to update its UI in response to user interaction or new data, it must ask its parent to pass it new props. We will cover how this happens when we learn about state and events in the next module. For now, just remember that props flow down and are not to be modified by the child.
This reading explains the concept of prop immutability, a core principle of React's data flow.
Read the section How props change over time. The key takeaway is the sentence: "Don’t try to “change props”."
Conclusion
Today, you've unlocked a crucial aspect of React development. By learning to pass data via props, you've transformed your components from static, isolated pieces of UI into dynamic, configurable building blocks—the very essence of a component library.
Here are the key takeaways from this lesson:
- Props are used to pass data from parent to child components. This data flow is unidirectional.
- You can think of props as arguments to a component function.
- Props are passed as attributes in JSX and received as a single object in the child component.
- Destructuring props (
const MyComponent = ({ prop1, prop2 }) => ...) is the standard convention for cleaner code. - You can set default values for props (
{ size = 100 }) to make components more robust. - Nested content is passed through the special
childrenprop, enabling flexible wrapper components. - Most importantly, props are read-only (immutable). A component must never modify the props it receives.
In our next lesson, we will build on this foundation. You've seen that you can pass any JavaScript data type as a prop, including arrays. We will learn how to take an array of data and use it to render a dynamic list of components, a pattern you'll use constantly in React applications.