React Props - Complete Guide
React props (short for properties) are how components talk to each other. They let you pass data from a parent component to a child component, making your components reusable and dynamic.
What Are Props?
Props are like function arguments in React. When you create a component, you can pass data to it as props. The component can then use that data to render different content.
Think of props as configuration options for your components. You give a component some props, and it uses those props to decide what to display.
Basic Props Usage
Passing Props
Here’s how you pass props to a component:
// Parent component
function App() {
return <Welcome name="Alice" age={25} />;
}
// Child component that receives props
function Welcome(props) {
return <h1>Hello, {props.name}! You are {props.age} years old.</h1>;
}Destructuring Props
You can make your code cleaner by destructuring props directly in the function parameters:
// Instead of this
function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Do this
function Welcome({ name, age }) {
return <h1>Hello, {name}! You are {age} years old.</h1>;
}Types of Props
String Props
String props are the most common type. You pass them in quotes:
function Button({ text }) {
return <button>{text}</button>;
}
function App() {
return <Button text="Click me!" />;
}Number Props
For numbers, use curly braces:
function UserProfile({ userId }) {
return <div>User ID: {userId}</div>;
}
function App() {
return <UserProfile userId={123} />;
}Boolean Props
Boolean props control component behavior:
function Button({ disabled, children }) {
return <button disabled={disabled}>{children}</button>;
}
function App() {
return (
<div>
<Button disabled={false}>Active Button</Button>
<Button disabled={true}>Disabled Button</Button>
</div>
);
}Array Props
Pass arrays to display lists of data:
function TodoList({ items }) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
function App() {
const todos = ["Learn React", "Build projects", "Get hired"];
return <TodoList items={todos} />;
}Object Props
Objects are great for passing related data together:
function UserCard({ user }) {
return (
<div>
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
<p>Role: {user.role}</p>
</div>
);
}
function App() {
const userData = {
name: "John Doe",
email: "[email protected]",
role: "Developer"
};
return <UserCard user={userData} />;
}Function Props
You can pass functions as props to handle events:
function Counter({ count, onIncrement, onDecrement }) {
return (
<div>
<p>Count: {count}</p>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
);
}
function App() {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<Counter
count={count}
onIncrement={increment}
onDecrement={decrement}
/>
);
}Props Best Practices
1. Use Descriptive Names
Make your prop names clear and descriptive:
// Good
<UserCard userName="Alice" userAge={25} />
// Bad
<UserCard n="Alice" a={25} />2. Provide Default Values
Use default props or default parameters:
// Using default parameters
function Button({ text = "Click me", type = "primary" }) {
return <button className={`btn-${type}`}>{text}</button>;
}
// Or using defaultProps (class components)
class Button extends React.Component {
static defaultProps = {
text: "Click me",
type: "primary"
};
}3. Validate Props
Use PropTypes for runtime validation:
import PropTypes from 'prop-types';
function UserCard({ name, age, email }) {
return (
<div>
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Email: {email}</p>
</div>
);
}
UserCard.propTypes = {
name: PropTypes.string.isRequired,
age: PropTypes.number,
email: PropTypes.string.isRequired
};
UserCard.defaultProps = {
age: 0
};4. Keep Components Small
Pass only the props a component actually needs:
// Instead of passing the whole user object
function UserAvatar({ user }) {
return <img src={user.avatar} alt={user.name} />;
}
// Pass only what's needed
function UserAvatar({ avatar, name }) {
return <img src={avatar} alt={name} />;
}Props vs State
It’s important to understand the difference between props and state:
- Props: Read-only data passed from parent to child
- State: Mutable data managed within a component
function ParentComponent() {
const [message, setMessage] = useState("Hello from parent");
return <ChildComponent message={message} />;
}
function ChildComponent({ message }) {
// Can't modify props directly
// message = "New message"; // This won't work!
return <p>{message}</p>;
}Spreading Props
Sometimes you want to pass all properties of an object as props:
const userProps = {
name: "Alice",
age: 25,
email: "[email protected]"
};
// Instead of this
<UserCard name={userProps.name} age={userProps.age} email={userProps.email} />
// Do this
<UserCard {...userProps} />Be careful when spreading props - only pass what the component actually needs.
Children Prop
React automatically passes children as a special prop:
function Card({ children, title }) {
return (
<div className="card">
<h2>{title}</h2>
<div className="card-content">
{children}
</div>
</div>
);
}
function App() {
return (
<Card title="Welcome">
<p>This is the card content.</p>
<button>Click me</button>
</Card>
);
}Render Props Pattern
Sometimes you pass a function as a prop that returns JSX:
function DataFetcher({ url, render }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => {
setData(data);
setLoading(false);
});
}, [url]);
if (loading) return <div>Loading...</div>;
return render(data);
}
function App() {
return (
<DataFetcher
url="/api/users"
render={data => (
<div>
<h2>Users</h2>
{data.map(user => (
<p key={user.id}>{user.name}</p>
))}
</div>
)}
/>
);
}Common Props Patterns
1. Configuration Props
Use props to configure component behavior:
function Modal({ isOpen, onClose, size = "medium", showCloseButton = true }) {
if (!isOpen) return null;
return (
<div className={`modal modal-${size}`}>
{showCloseButton && (
<button onClick={onClose} className="close-button">×</button>
)}
<div className="modal-content">
{/* Modal content here */}
</div>
</div>
);
}2. Styling Props
Pass styling information through props:
function Button({ variant = "primary", size = "medium", children }) {
const className = `btn btn-${variant} btn-${size}`;
return <button className={className}>{children}</button>;
}
function App() {
return (
<div>
<Button variant="primary" size="large">Big Primary Button</Button>
<Button variant="secondary" size="small">Small Secondary Button</Button>
</div>
);
}3. Conditional Props
Use props to control what gets rendered:
function Alert({ type, message, showIcon = true }) {
const icons = {
success: "✓",
error: "✗",
warning: "⚠",
info: "ℹ"
};
return (
<div className={`alert alert-${type}`}>
{showIcon && <span className="alert-icon">{icons[type]}</span>}
<span className="alert-message">{message}</span>
</div>
);
}Props and Component Reusability
Good prop design makes components highly reusable:
// Bad - Hard to reuse
function WelcomeMessage() {
return <h1>Welcome, Alice!</h1>;
}
// Good - Highly reusable
function WelcomeMessage({ name, greeting = "Welcome" }) {
return <h1>{greeting}, {name}!</h1>;
}
// Can be used in many ways
<WelcomeMessage name="Alice" />
<WelcomeMessage name="Bob" greeting="Hello" />
<WelcomeMessage name="Carol" greeting="Good morning" />Summary
Props are fundamental to React development. Remember these key points:
- Props are read-only and passed from parent to child
- Use descriptive prop names
- Provide default values when appropriate
- Validate props with PropTypes
- Keep components focused and pass only necessary props
- Use the children prop for flexible content composition
Mastering props will make you a better React developer and help you build more maintainable, reusable components.
External Resources:
- React Official Docs - Components and Props
- React PropTypes Documentation
- React Patterns - Render Props
Related Tutorials: