In React, props (short for properties) are used to pass data from a parent component to a child component. They enable communication between components and make components reusable and dynamic.
Props are read-only — the child component can access them but cannot modify them. Any changes to data should happen in state (usually in the parent), and updated values are passed down again as props.
? One-way data flow: Parent ➜ Child via props
props object.A parent component can pass props down to a child component just like function arguments. The child receives all props inside a single object called props.
// App.js (parent component passing data to children)
import Greeting from "./Greeting";
function App() {
return (
<div>
<Greeting name="Aman" />
<Greeting name="Riya" />
</div>
);
}
// Greeting.js (child component using the received prop)
function Greeting(props) {
return <h2>Hello, {props.name}!</h2>;
}
export default Greeting;
App renders the Greeting component twice with different name props.
<Greeting name="Aman" /> ➜ Hello, Aman!<Greeting name="Riya" /> ➜ Hello, Riya!The same component is reused with different data values.
You can pass multiple props to a single component. React simply groups them into the props object.
// Passing multiple props to the Profile component
<Profile name="Megha" age={22} city="Pune" />
// Profile component reading values from props
function Profile(props) {
return (
<div>
<h3>Name: {props.name}</h3>
<p>Age: {props.age}</p>
<p>City: {props.city}</p>
</div>
);
}
The Profile component receives a props object with three properties: name, age, and city. It then uses them to display user information inside JSX.
Instead of accessing every value as props.name, props.age, etc., you can destructure props in the function parameter list for cleaner code.
// Destructuring props directly in the function parameter
function Profile({ name, age, city }) {
return (
<div>
<h3>Name: {name}</h3>
<p>Age: {age}</p>
<p>City: {city}</p>
</div>
);
}
Now, you can use name, age, and city directly without typing props. every time. This is especially useful when components have many props.
You can pass functions as props to allow child components to notify or send data back to their parents. This pattern is often called a callback.
// Parent defines a function and passes it down as a prop
function Parent() {
const handleMessage = (msg) => alert(msg);
return <Child sendMessage={handleMessage} />;
}
// Child calls the parent's function when the button is clicked
function Child({ sendMessage }) {
return (
<button onClick={() => sendMessage("Hello Parent!")}>
Click to Send Message
</button>
);
}
When the button in Child is clicked, it calls sendMessage("Hello Parent!"). This actually runs handleMessage inside Parent, showing an alert. The data flows up via function props.
Props can carry complex data types like objects and arrays. This is useful when you need to pass a group of related values.
// Creating an object and passing it as a single prop
const user = { name: "Arjun", age: 25 };
<UserCard data={user} />;
// UserCard component reading fields from the object
function UserCard({ data }) {
return (
<div>
<h3>{data.name}</h3>
<p>Age: {data.age}</p>
</div>
);
}
Instead of passing separate name and age props, we pass one data object. This keeps the component flexible and allows you to add more fields later without changing the prop list.
Props must never be changed inside the child component. If you need to update data, keep it in state (usually in the parent component) and pass the updated value and/or a function as props.
// ❌ Wrong: trying to modify props directly
props.name = "Changed"; // This will not work and should never be done
// ✅ Correct: keep data in state and pass it down as props
function Parent() {
const [name, setName] = useState("Riya");
return <Child name={name} updateName={() => setName("Aman")} />;
}
In the correct example, the Parent owns the name state. When it wants to change the name, it calls setName and passes the new value down again via props. The Child can ask for an update by calling updateName, but it never changes props directly.
Parent component that passes name and age to a Child component.Child component using JSX.Parent to Child that logs a custom message (for example, "Button clicked from Child") when a button is clicked.Child component to use destructuring for its props.user with name, age, city) as a single prop and render its fields.Goal: Get comfortable sending data, functions, and complex objects between React components using props, while remembering that props are always read-only.