React Passing Data with Props
Table of Contents + −
In the last lesson on React Props you saw the basic idea of sending data into a component. Now let’s see how to pass different kinds of data, like numbers, true/false values, and lists, and reuse one component with different data each time.
🤔 Why does this matter?
The whole point of props is to stop you from copying the same component again and again with hard-coded text inside. Here’s why that’s a big deal.
- Without props, you would write a separate component for every single card, every greeting, every product. That’s painful, right?
- With props, you build the component once. Then you pass in different data each time you use it.
- One
ProductCardcan show a phone, a laptop, headphones, anything. Same code, different data. - This is how real apps work. A product list on Amazon is one card component repeated with different props.
So props are what make a component reusable. You write it once, then feed it data.
🧩 The two ways to pass a value
Here’s the one rule that trips up most beginners. When you pass a prop, you either use quotes or curly braces.
- Use quotes
"..."only for a plain text string. - Use curly braces
{...}for everything else, like numbers, true/false, arrays, and objects. - Curly braces basically mean “this is real JavaScript, not text”.
This small example shows both ways side by side.
function App() { return ( <ProductCard name="Wireless Headphones" // string → quotes price={129} // number → curly braces inStock={true} // boolean → curly braces /> );}The thing to notice here.
nameuses quotes because it’s just text.priceandinStockuse curly braces because a number and a boolean are JavaScript values, not text.
Easy rule to remember
Text in quotes. Everything else in curly braces. If you are passing a number,
a true/false, a list, or an object, reach for the { }.
🔢 Passing numbers and booleans
Numbers and booleans both need curly braces. This is where the most common mistake happens, so look closely.
// ❌ Wrong - price is passed as text "129", not a number<ProductCard name="Phone" price="129" inStock="false" />
// ✅ Right - curly braces make them a real number and a real boolean<ProductCard name="Phone" price={129} inStock={false} />Let’s walk through what goes wrong in the first line.
price="129"sends the text"129", not the number129. So if the child tries to doprice * 2, the math gets confused.inStock="false"is even worse. The string"false"is actually truthy in JavaScript, so anif (inStock)check would run as if it weretrue. Not what you wanted.- The fixed line uses
{129}and{false}, so the child gets a real number and a real boolean.
The classic boolean trap
inStock="false" is the text “false”, and any non-empty text counts as true.
So your “out of stock” check would never fire. Always use {false} for a real
boolean.
📋 Passing arrays and objects
A list of things is an array. A group of related fields is an object. Both go inside curly braces too, because both are JavaScript values.
function App() { const tags = ["new", "popular", "sale"]; const seller = { name: "Riya", rating: 4.8 };
return ( <ProductCard name="Laptop" price={899} tags={tags} // array → curly braces seller={seller} // object → curly braces /> );}Here’s what’s happening, step by step.
- We make a
tagsarray and asellerobject first, as normal JavaScript variables. - Then we pass them down with
{tags}and{seller}. The curly braces say “use this actual value”. - You could also write the object inline, but then you need double braces, like
seller={{ name: "Riya", rating: 4.8 }}. The outer braces mean JavaScript, the inner braces are the object itself.
Why double braces?
seller={{ ... }} is not special React syntax. It’s just { for “JavaScript
here” plus the { } of the object. Two different braces doing two different
jobs.
📥 Reading the props in the child
So you’ve passed the data in. Every component receives one props object, and the cleanest way to read it is destructuring.
function ProductCard({ name, price, inStock }) { return ( <div className="product-card"> <h3>{name}</h3> <p>Price: ${price}</p> <p>{inStock ? "In stock" : "Sold out"}</p> </div> );}Let’s read this top to bottom.
{ name, price, inStock }in the parentheses pulls each prop out by name. That’s destructuring.- The names here must match the names you passed from the parent, exactly.
pricematchesprice. - Inside the JSX, you use curly braces again to show a value, like
{name}and{price}. - The line
{inStock ? "In stock" : "Sold out"}checks the boolean and shows the right text.
Names must match exactly
If the parent passes price but the child reads cost, you get undefined.
React doesn’t rename anything for you, so keep the names identical on both
sides.
🔁 Reusing one component with different props
This is the payoff. You wrote ProductCard once. Now you can render it many times, each with its own data.
function App() { return ( <div> <ProductCard name="Headphones" price={129} inStock={true} /> <ProductCard name="Keyboard" price={49} inStock={true} /> <ProductCard name="Webcam" price={75} inStock={false} /> </div> );}See how clean that is? Same component, three times, three different products.
- One component definition. Zero copy-paste of the card markup.
- Each card shows its own name, price, and stock status.
- Want a fourth product? Add one more line. That’s it.
- Change the card design once, and all three update together.
What you'd see on the page
HeadphonesPrice: $129In stock
KeyboardPrice: $49In stock
WebcamPrice: $75Sold out⚠️ A common mistake: wrong prop name
Besides forgetting curly braces, the other thing people hit a lot is a name mismatch between parent and child. Watch this one.
// ❌ Wrong - parent sends "title", child reads "name" → name is undefined<ProductCard title="Mouse" price={25} />function ProductCard({ name, price }) { return <h3>{name}</h3>; // shows nothing}
// ✅ Right - both sides use the same name "name"<ProductCard name="Mouse" price={25} />function ProductCard({ name, price }) { return <h3>{name}</h3>; // shows "Mouse"}Here’s the lesson from these two blocks.
- In the wrong version the parent calls it
title, but the child looks forname. Sonameisundefinedand the heading shows nothing. - React won’t warn you loudly here. The card just renders blank, which is confusing.
- The fix is simple. Use the same prop name on both sides. Whatever you pass it as, read it by that exact name.
When something shows blank
An empty value on screen is almost always a name mismatch or a missing prop. First thing to check, do the prop names match on both sides?
🧩 What You’ve Learned
- ✅ Strings are passed in quotes
"...", everything else in curly braces{...} - ✅ Numbers and booleans need
{ }, never quotes, or they become text - ✅
inStock="false"is text and counts as true, so use{false}for a real boolean - ✅ Arrays and objects go in curly braces too, and inline objects need double braces
{{ }} - ✅ The child reads props by destructuring, and the names must match the parent exactly
- ✅ One component can be reused many times with different prop values to build dynamic UIs
- ✅ A blank value on screen usually means a wrong or missing prop name
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
How should you pass the number 50 as a 'price' prop?
Why: Numbers need curly braces. price={50} passes a real number, while price="50" would pass the text "50".
- 2
What does inStock="false" actually give the child component?
Why: "false" is a non-empty string, and any non-empty string is truthy in JavaScript. Use inStock={false} for a real boolean.
- 3
The parent passes title="Mouse" but the child reads { name }. What shows up?
Why: Prop names must match on both sides. The child looks for name, which was never passed, so it is undefined and renders blank.
- 4
Why do you write seller={{ name: "Riya" }} with double braces?
Why: The outer { } says 'JavaScript value here' and the inner { } is the object literal itself. Two braces, two jobs.
🚀 What’s Next?
Now you can pass any kind of data into a component and reuse it with different values. But what happens when a prop is missing? Next you’ll learn how to set fallback values so your components never break on missing data.