In React, destructuring props is a clean and efficient way to extract values from the props object. Instead of repeatedly writing expressions like props.name or props.age, you can destructure them once and use the variables directly. This improves readability, maintainability, and reduces repetition.
Destructuring works with:
name, age, city)user.address.city)✨ Goal: Write cleaner, shorter, and safer React components.
props object.props, then destructure inside the function body.address.city.In plain JavaScript, object destructuring looks like this:
// JavaScript object destructuring basics
const user = { name: "Aman", age: 22, city: "Pune" };
const { name, age, city } = user;
console.log(name, age, city);
In React, the same idea applies to component props. You can destructure:
function User({ name, age }) { ... }const { name, age } = props;const { address: { city, country } } = user;function Greeting({ name = "Guest" }) { ... }Here the component accesses every property through props. This works, but becomes repetitive and harder to maintain when there are many props.
// Accessing values directly from the props object
function User(props) {
return (
<div>
<h3>Name: {props.name}</h3>
<p>Age: {props.age}</p>
<p>City: {props.city}</p>
</div>
);
}
As the component grows, writing props. everywhere can make the code noisy and less readable.
The most common pattern is to destructure the props directly inside the function parameter list. This makes the JSX cleaner and focuses on what you actually use.
// Destructuring props directly in the parameter list
function User({ name, age, city }) {
return (
<div>
<h3>Name: {name}</h3>
<p>Age: {age}</p>
<p>City: {city}</p>
</div>
);
}
This keeps the JSX neat and makes it obvious which props the component depends on.
Sometimes you may want the full props object first (e.g., for logging or conditional logic) and then destructure it.
// Destructuring props inside the function body
function User(props) {
const { name, age, city } = props;
return (
<div>
<h3>Name: {name}</h3>
<p>Age: {age}</p>
<p>City: {city}</p>
</div>
);
}
This approach is helpful when you want to run some logic before returning JSX while still keeping access to the original props object.
Props can contain nested objects. With nested destructuring, you can directly extract deep fields like city and country from a user object.
// Destructuring nested fields from a user prop
function Profile({ user }) {
const { name, address: { city, country } } = user;
return (
<div>
<h3>Name: {name}</h3>
<p>City: {city}, {country}</p>
</div>
);
}
// Usage example
<Profile user={{ name: "Aman", address: { city: "Pune", country: "India" } }} />
This keeps your JSX clean but be careful: if address is sometimes undefined, you may need optional chaining or safe defaults to avoid errors.
Default values ensure your component still works even if some props are not passed. This is very useful for optional props.
// Providing default values directly while destructuring
function Greeting({ name = "Guest", message = "Welcome!" }) {
return <h3>Hello {name}, {message}</h3>;
}
// Usage: name and message fall back to their defaults
<Greeting /> // Output: Hello Guest, Welcome!
This pattern avoids undefined showing up in the UI and makes your components safer and more predictable.
Here is a slightly more complex example that combines simple props, nested props, and a real-world use-case like showing a product card.
// Destructuring nested props in a product component
function Product({ title, price, details: { category, rating } }) {
return (
<div>
<h3>{title}</h3>
<p>Price: ₹{price}</p>
<p>Category: {category}</p>
<p>Rating: {rating}/5</p>
</div>
);
}
// Usage example
<Product
title="T-Shirt"
price={499}
details={{ category: "Clothing", rating: 4.5 }}
/>
Notice how we never write props.title or props.details.category. Destructuring keeps the code shorter and easier to read.
Let’s focus on the Greeting component to understand how destructuring with default values affects the output.
JSX:
<Greeting />
Rendered Output:
Hello Guest, Welcome!
Because we used {`name = "Guest"`} and {`message = "Welcome!"`} in the destructuring, React automatically falls back to these values when no props are passed. This prevents awkward outputs like Hello undefined, undefined.
undefined in the UI.UserCard component that receives name, email, and address as props.function UserCard({ name, email, address }) { ... }).address: { city, country } and destructure city and country too."Unknown" for city or "N/A" for email).props object once to see how React passes data, then rely on destructured variables in the JSX.Goal: Practice extracting props using destructuring so you can write cleaner, maintainable React components that are easy to read and debug.