React has come a long way since I started building front-end applications over eight years ago.
In the early days, we spent a lot of time typing this.props over and over again in class components.
When functional components became the standard, handling data became much more elegant.
However, I still see many developers passing around bulky props objects that make the code harder to read.
In this tutorial, I will show you how to use props destructuring to keep your React code clean and professional.
Why You Should Use Props Destructuring
In my experience, destructuring is one of the easiest ways to improve the readability of your components.
When you destructure, you declare exactly which variables your component expects right at the top.
It helps other developers on your team understand the component’s API without scrolling through a hundred lines of JSX.
Plus, it saves you from typing the word “props” every time you want to display a simple value like a name or an address.
Method 1: Destructuring Props Directly in the Function Signature
This is my go-to method for almost every component I build.
By destructuring inside the parentheses of your function, you immediately see what the component needs to render.
Let’s look at a practical example involving a California-based real estate listing.
import React from 'react';
// Destructuring props directly in the argument list
const RealEstateCard = ({ propertyName, price, location, sqft }) => {
return (
<div style={{ border: '1px solid #ccc', padding: '20px', borderRadius: '8px' }}>
<h1>{propertyName}</h1>
<p><strong>Price:</strong> ${price.toLocaleString()}</p>
<p><strong>Location:</strong> {location}</p>
<p><strong>Size:</strong> {sqft} sq. ft.</p>
<button onClick={() => alert(`Inquiry sent for ${propertyName}`)}>
Contact Realtor
</button>
</div>
);
};
// Usage Example
const App = () => {
return (
<div className="App">
<RealEstateCard
propertyName="Luxury Condo in Santa Monica"
price={1250000}
location="Santa Monica, CA"
sqft={1200}
/>
</div>
);
};
export default App;You can see the output in the screenshot below.

I find this method incredibly clean because it treats the props like local variables. You don’t have to look through the function body to find out what data is being used.
Method 2: Destructure Props Inside the Component Body
Sometimes, you might need to use the entire props object before you break it down.
I usually use this method when I need to log the full props object for debugging or when I’m passing the rest of the props to a child component.
Here is how I implement destructuring inside the function body using a New York City taxi fare calculator example.
import React from 'react';
const TaxiReceipt = (props) => {
// Destructuring inside the component body
const { pickupLocation, dropoffLocation, fare, tip } = props;
const total = fare + tip;
return (
<div style={{ backgroundColor: '#f9f9f9', padding: '15px', maxWidth: '400px' }}>
<h3>NYC Yellow Cab Receipt</h3>
<p>From: {pickupLocation}</p>
<p>To: {dropoffLocation}</p>
<hr />
<p>Fare: ${fare.toFixed(2)}</p>
<p>Tip: ${tip.toFixed(2)}</p>
<h4>Total Charge: ${total.toFixed(2)}</h4>
</div>
);
};
// Usage Example
const App = () => {
return (
<div className="App">
<TaxiReceipt
pickupLocation="JFK Airport"
dropoffLocation="Times Square"
fare={52.00}
tip={10.50}
/>
</div>
);
};
export default App;You can see the output in the screenshot below.

This approach is helpful when the logic is a bit more complex.
It allows you to keep the function signature short while still getting the benefits of clean variable names.
Method 3: Handle Nested Destructuring
In real-world applications, data is rarely flat. I often deal with complex objects, such as user profiles that contain nested address or social media information.
You can destructure these nested objects in one go, though you should be careful not to make it too hard to read.
Let’s look at a “Member Profile” for a tech hub in Seattle.
import React from 'react';
const MemberProfile = ({ user: { name, role, contact: { email, linkedin } } }) => {
return (
<div style={{ borderLeft: '5px solid #0078d4', paddingLeft: '10px' }}>
<h2>{name}</h2>
<p><strong>Role:</strong> {role}</p>
<p><strong>Email:</strong> {email}</p>
<a href={linkedin} target="_blank" rel="noreferrer">LinkedIn Profile</a>
</div>
);
};
// Usage Example
const App = () => {
const userData = {
name: "Sarah Jenkins",
role: "Senior Azure Architect",
contact: {
email: "sarah.j@seattletech.com",
linkedin: "https://linkedin.com/in/sarahjenkins"
}
};
return (
<div className="App">
<MemberProfile user={userData} />
</div>
);
};
export default App;You can see the output in the screenshot below.

While nested destructuring is powerful, I usually recommend going only one or two levels deep.
If the object is deeper than that, your code might start looking like “callback hell,” but for variables.
Use Default Values with Destructuring
One of the best tricks I’ve learned is setting default values while destructuring. This ensures your component doesn’t break if a specific prop isn’t passed from the parent.
Imagine we are building a simple “State Tax Calculator” where the tax rate might not always be provided.
import React from 'react';
// Setting a default value for taxRate (e.g., 6% for a generic state)
const TaxCalculator = ({ amount, stateName, taxRate = 0.06 }) => {
const taxAmount = amount * taxRate;
return (
<div style={{ padding: '10px', border: '1px solid black' }}>
<h3>Tax Estimate for {stateName}</h3>
<p>Purchase Amount: ${amount}</p>
<p>Current Tax Rate: {(taxRate * 100).toFixed(1)}%</p>
<p>Estimated Tax: ${taxAmount.toFixed(2)}</p>
</div>
);
};
// Usage Example
const App = () => {
return (
<div className="App">
{/* Uses the default 6% rate */}
<TaxCalculator stateName="Florida" amount={100} />
{/* Uses the specific 7.25% rate */}
<TaxCalculator stateName="California" amount={100} taxRate={0.0725} />
</div>
);
};
export default App;This prevents the “undefined” errors that often crash React apps in production.
Use the Spread Operator (…) with Destructuring
Sometimes you want to pull out one or two props and pass the rest to an underlying HTML element.
I find this incredibly useful when creating reusable UI components like custom buttons or inputs.
import React from 'react';
const CustomInput = ({ label, ...rest }) => {
return (
<div style={{ marginBottom: '15px' }}>
<label style={{ display: 'block' }}>{label}</label>
{/* The rest operator collects all other props and spreads them here */}
<input
style={{ padding: '8px', width: '250px' }}
{...rest}
/>
</div>
);
};
// Usage Example
const App = () => {
return (
<div className="App" style={{ padding: '20px' }}>
<CustomInput
label="Enter Your US Zip Code"
type="number"
placeholder="e.g. 90210"
onChange={(e) => console.log(e.target.value)}
/>
</div>
);
};
export default App;By using …rest, you don’t have to manually pass type, placeholder, and onChange to the input element.
It makes your custom components much more flexible.
In this tutorial, I showed you several ways to destructure props in React functional components.
I’ve found that using these techniques not only makes my code cleaner but also significantly faster to write.
Other React Tutorials you may like:
- Component-Based Architecture in React
- How to Use React Select Component
- How to Use react-tag-input-component in React
- How to Use React Pivot Table

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.