On this page
Props
Props (properties) pass data from parent to child components. Props are read-only — never modify them inside the child.
Passing Props
function Greeting({ name, age }) {
return (
<div>
<h1>Hello, {name}!</h1>
<p>You are {age} years old.</p>
</div>
);
}
// Parent
<Greeting name="Alice" age={25} />
Destructuring Props
// In parameter
function UserCard({ name, email, avatar }) {
return (
<div>
<img src={avatar} alt={name} />
<h2>{name}</h2>
<p>{email}</p>
</div>
);
}
// Or inside function
function UserCard(props) {
const { name, email } = props;
return <h2>{name}</h2>;
}
Default Props
function Button({ label = 'Click me', variant = 'primary', onClick }) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
);
}
<Button /> // "Click me", primary
<Button label="Submit" /> // "Submit", primary
<Button variant="danger" label="Delete" />
Passing Functions as Props
function SearchBar({ onSearch }) {
const [query, setQuery] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onSearch(query);
};
return (
<form onSubmit={handleSubmit}>
<input value={query} onChange={e => setQuery(e.target.value)} />
<button type="submit">Search</button>
</form>
);
}
// Parent
function App() {
const handleSearch = (query) => console.log('Searching:', query);
return <SearchBar onSearch={handleSearch} />;
}
Spread Props
function Input({ label, ...inputProps }) {
return (
<div>
<label>{label}</label>
<input {...inputProps} />
</div>
);
}
<Input label="Email" type="email" placeholder="[email protected]" required />
Props Are Immutable
function BadComponent(props) {
props.name = 'Changed'; // ERROR — never mutate props
return <h1>{props.name}</h1>;
}
If you need to change data, use state (next chapter).
PropTypes (Optional)
npm install prop-types
import PropTypes from 'prop-types';
function User({ name, age, email }) {
return <div>{name}, {age}</div>;
}
User.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
email: PropTypes.string
};
User.defaultProps = {
age: 0
};
With TypeScript, use interfaces instead of PropTypes (see TypeScript with React).
Props flow down the component tree — for sharing data across distant components, use Context or state management libraries.