Introduction
In React, components are the building blocks of your application. They help you break down the UI into manageable pieces. To make these components reusable and dynamic, React uses something called props.
What Are Props?
Props (short for "properties") are read-only inputs passed from a parent component to a child. They allow you to pass data and behavior into components, enabling reusability and dynamic rendering.
Think of props as function arguments, and components as functions, props let you customize what each component displays or does.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
In the above example, props.name allows the Welcome component to display different names based on what is passed to it.
How to Use Props in React?
To use props.
- Define props in your child component.
- Pass them from the parent component using HTML-like syntax.
File Structure
📁 src/
├── 📁 components/
│ └── 📄 Card.js
│
├── 📁 data/
│ └── 📄 users.js
│
└── 📄 App.js
Card.js – Reusable Component
const Card = (props) => {
return (
<div style={{ border: "1px solid #ddd", padding: "1rem", margin: "1rem",
display: "inline-block" }}>
<h2>{props.name}</h2>
<p>Age: {props.age}</p>
<p>Profession: {props.profession}</p>
</div>
);
};
export default Card;
- The card is a React functional component that takes one parameter: props
- props is a JavaScript object that is going to contain all the data that is being passed to this component from its parent.
- {props.name} displays the value of the name prop inside an <h2>.
- {props.age} and {props.profession} do the same for age and profession.
Using Destructuring in the Card Component
Now let's rewrite the same card component using destructuring for cleaner and more concise code.
If you want to learn more about destructuring in JavaScript, check out: Destructuring in JavaScript
Here, Instead of accessing props.name, props.age, and props.profession, we destructure those values directly in the function parameters: ({ name, age, profession })
const Card = ({ name, age, profession }) => {
return (
<div style={{ border: "1px solid #ddd", padding: "1rem", margin: "1rem", display: "inline-block" }}>
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Profession: {profession}</p>
</div>
);
};
export default Card;
How to Call This Component from the Parent?
You can now use the Card component in your parent component (like App.js) and pass the required props.
<Card name="Alex" age={28} profession="Engineer" />
![Alex]()
Full Version of App.js
Below is the complete code for the App component. In this example, the App component acts as the parent, and the Card is the child component since it is being rendered (or "nested") inside Athe pp.
import './App.css';
import Card from './components/Card'
function App() {
return (
<div className="App">
<Card name="Alex" age={28} profession="Engineer" />
</div>
);
}
export default App;
Why Is Card a Child Component?
In React, when one component renders another, the rendered component is considered a child. This structure helps organize the UI and pass data using props from parent to child.
Using External Data Instead of Hardcoded Values
So far, we've tested our card component using hardcoded values, like passing "Alex" directly. However, in real-world apps, data often comes from external sources or files. Let's simulate that by creating a separate data file.
//data/users.js
const users = [
{
name: "Alex",
age : 25,
profession : "Engineer"
},
{
name: "Gloria",
age : 23,
profession : "Designer"
},
{
name: "Martin",
age : 25,
profession : "DevOps"
}
]
export default users;
We’ve now moved our user data to a separate file called users.js.
Importing and Passing Data in App.js
Now that our data is stored externally, we can import it into our App-component and pass it as props to Card.
import './App.css';
import Card from './components/Card'
import users from "./data/users";
function App() {
return (
<div className="App">
<Card
name={users[0].name}
age={users[0].age}
profession={users[0].profession}
/>
</div>
);
}
export default App;
Here, we’re accessing the first user (Alex) from the user's array and passing their details as props to the card component. For the card component, there is no change, this component receives dynamic values via props and renders them accordingly.
Instead of passing each prop individually, you can use the spread operator to pass all properties of an object at once: This automatically spreads all key-value pairs (like name, age, and profession) from the user object into the Card component as props.
<Card {...users[1]} />
![Output]()
Rendering Multiple Users with .map()
{
users.map((user, index) => (
<Card key={index} {...user} />
))
}
This code dynamically renders a Card for every user in the array. By using the spread operator, the code stays scalable even as your data grows.
![Result]()
Let's touch on Destructuring in detail.
Destructuring lets you extract values from an object or array.
Without Destructuring
function Card(props) {
return <h2>{props.name}</h2>;
}
With Destructuring
function Card({ name }) {
return <h2>{name}</h2>;
}
You can also set default values.
function Card({ name = "Guest" }) {
return <h2>{name}</h2>;
}
Common Mistakes to Avoid
Mistake |
Why it's a problem |
Passing props that aren't used |
This leads to unnecessary re-renders and confusion |
Forgetting key in lists |
React needs unique key props for dynamic lists |
Destructuring a non-existent property |
Results in undefined or runtime errors |
Modifying props inside child components |
Props are read-only; use state instead |
Assuming all data will always be present |
Use default values or conditional rendering |
Using complex expressions directly in JSX |
Makes JSX hard to read; better to use variables |
Best Practices & Norms to Follow
Best Practice |
Why it helps |
Destructure props in the function parameter |
Cleaner, more readable code |
Use default values when destructuring |
Prevents undefined rendering |
Validate prop types with PropTypes (optional) |
Helps catch type-related bugs |
Use the spread operator carefully |
Ensure only valid and expected props are passed |
Use key prop when rendering lists |
Prevents rendering bugs in dynamic lists |
Keep components focused and small |
Easier to reuse, test, and maintain |
Conclusion
React props make components reusable, and dynamic. By understanding different ways of passing props, manually, via array indexing, or using the spread operator and applying destructuring, you can write cleaner and more maintainable React code.
By avoiding common mistakes and following best practices, you'll build components that are easier to read, debug, and reuse across your projects.