Props (short for properties) are the fundamental mechanism for transferring data from a parent component to a child component in React. This process is essential for making components dynamic, configurable, and reusable.
1. Unidirectional Data Flow and Read-Only Props
A core principle of React is Unidirectional Data Flow, meaning data moves in a single direction: from top to bottom (parent to child).
- The Parent component owns the data.
- The Child component receives the data via its
propsobject. - The child component treats props as read-only (immutable). It cannot directly change the prop value it receives; it can only use it to render the UI.
2. Passing Data via JSX Attributes
Data is passed to the child component by assigning values to attributes on the component’s JSX tag. These attributes become the keys in the child component’s props object.
Execution Example: Defining and Using Props
We will create two files in your my-first-app/src directory:
UserBadge.js(The Child Component: Receives and renders props)App.js(The Parent Component: Owns and passes the data)
A. UserBadge.js (The Child Component)
Create or open UserBadge.js and paste the following. Note the explicit use of the props argument.
import React from 'react';
// The component function accepts the 'props' object as its argument.
function UserBadge(props) {
// Access data using dot notation: props.username and props.status
const statusColor = props.status === 'Online' ? 'green' : 'red';
return (
<div style={{ padding: '10px', margin: '10px', border: `1px solid ${statusColor}`, borderRadius: '5px' }}>
<h3>User: {props.username}</h3>
<p style={{ color: statusColor }}>Status: {props.status}</p>
</div>
);
}
export default UserBadge;
B. App.js (The Parent Component)
Open App.js and replace its content with the following:
import React from 'react';
import UserBadge from './UserBadge';
function App() {
const primaryUser = {
name: "Alex Johnson",
online: true
};
return (
<div className="Dashboard">
<h1>Active Users</h1>
{/* 1. Pass data from the parent state/variable to the child component.
The attributes 'username' and 'status' become the props keys.
*/}
<UserBadge
username={primaryUser.name}
status={primaryUser.online ? 'Online' : 'Offline'}
/>
{/* 2. Demonstrating reusability with hardcoded props */}
<UserBadge
username="Sarah Connor"
status="Online"
/>
</div>
);
}
export default App;
- Local Execution: Run
npm startin your project’s terminal. - Observation: The
Appcomponent successfully renders two instances ofUserBadge, each customized by the distinctusernameandstatusprops provided by the parent.
3. Destructuring Props (Modern Best Practice)
While using props.username is functional, modern JavaScript favors destructuring. This extracts the necessary keys directly from the props object within the function signature, resulting in cleaner and more explicit code.
Refactored UserBadge.js using Destructuring:
import React from 'react';
// Destructure the required keys { username, status } directly from the incoming props object
function UserBadge({ username, status }) {
const statusColor = status === 'Online' ? 'green' : 'red';
return (
<div style={{ padding: '10px', margin: '10px', border: `1px solid ${statusColor}`, borderRadius: '5px' }}>
{/* Access keys directly without the 'props.' prefix */}
<h3>User: {username}</h3>
<p style={{ color: statusColor }}>Status: {status}</p>
</div>
);
}
export default UserBadge;
This pattern is widely adopted as it clearly documents the component’s required inputs at a glance.
