Learn to build reusable React components, pass data with props, and compose components together to create complex UIs.
In React, a component is a function that returns JSX. Components let you split your UI into independent, reusable pieces. Think of them like custom HTML elements that you define yourself.
A function component is simply a JavaScript function with two rules:
<MyButton />) from regular HTML elements (<button>).null if it should render nothing).function UserCard() {
return (
<div className="card">
<h2>John Doe</h2>
<p>Software Developer</p>
</div>
);
}You can also write components as arrow functions:
const UserCard = () => (
<div className="card">
<h2>John Doe</h2>
<p>Software Developer</p>
</div>
);Both styles are valid and functionally identical. The regular function syntax is slightly more common in React documentation and tutorials.
Once defined, you use a component like an HTML tag:
function App() {
return (
<div>
<UserCard />
<UserCard />
<UserCard />
</div>
);
}This renders three identical user cards. But identical cards are not very useful — we need a way to make each one different. That is where props come in.
Props (short for "properties") are the mechanism for passing data from a parent component to a child component. Props make components dynamic and reusable — the same component can render different content depending on the props it receives.
Props are passed as attributes in JSX, just like HTML attributes:
<UserCard name="Alice" role="Designer" />
<UserCard name="Bob" role="Developer" />Inside the component, props are received as a single object parameter:
function UserCard(props) {
return (
<div className="card">
<h2>{props.name}</h2>
<p>{props.role}</p>
</div>
);
}The props object for the first <UserCard> would be { name: 'Alice', role: 'Designer' }.
Destructuring props is the preferred pattern because it makes the code cleaner and immediately shows which props the component expects:
function UserCard({ name, role }) {
return (
<div className="card">
<h2>{name}</h2>
<p>{role}</p>
</div>
);
}You can pass any JavaScript value as a prop — strings, numbers, booleans, arrays, objects, and even functions:
<ProductCard
title="Laptop"
price={999}
inStock={true}
tags={['electronics', 'sale']}
onBuy={() => console.log('Bought!')}
/>Note: String props use quotes, but all other types use curly braces {}.
Default values for props can be set using JavaScript's default parameter syntax:
function Button({ text = 'Click me', color = 'blue' }) {
return (
<button style={{ backgroundColor: color }}>
{text}
</button>
);
}
// Uses defaults:
<Button />
// Overrides text:
<Button text="Submit" />
// Overrides both:
<Button text="Delete" color="red" />The children prop is a special prop that contains whatever you put between the opening and closing tags of a component:
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
// Usage:
<Card>
<h2>Title</h2>
<p>Some content goes here.</p>
</Card>The children prop is powerful because it lets you create wrapper components — components that provide structure or styling while allowing any content inside. This pattern is used everywhere in React:
function Layout({ children }) {
return (
<div className="layout">
<nav>Navigation</nav>
<main>{children}</main>
<footer>Footer</footer>
</div>
);
}
function App() {
return (
<Layout>
<h1>Home Page</h1>
<p>Welcome to my site!</p>
</Layout>
);
}The children prop makes Layout reusable — you can wrap any content with the same navigation and footer.
React encourages you to break your UI into a tree of small, focused components. Each component should do one thing well. This is called composition.
Consider building a user profile page:
function Avatar({ src, alt }) {
return <img src={src} alt={alt} className="avatar" />;
}
function UserInfo({ name, bio }) {
return (
<div>
<h3>{name}</h3>
<p>{bio}</p>
</div>
);
}
function ProfileCard({ user }) {
return (
<div className="profile-card">
<Avatar src={user.avatar} alt={user.name} />
<UserInfo name={user.name} bio={user.bio} />
</div>
);
}
function App() {
const user = {
name: 'Alice',
bio: 'React developer',
avatar: 'alice.jpg'
};
return <ProfileCard user={user} />;
}Notice how each component is small and focused:
Avatar only handles displaying an image.UserInfo only displays a name and bio.ProfileCard composes them together.App provides the data.Important rules about props:
// Never do this — props are read-only!
function Bad(props) {
props.name = 'hacked'; // This violates React's rules
return <h1>{props.name}</h1>;
}<div id="root"></div>
<script src="https://unpkg.com/react@19/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@19/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Badge({ label, color = "gray" }) {
return (
<span style={{
backgroundColor: color,
color: "white",
padding: "2px 8px",
borderRadius: "4px",
fontSize: "12px",
marginRight: "4px"
}}>
{label}
</span>
);
}
function UserCard({ name, role, skills }) {
return (
<div style={{ border: "1px solid #ccc", padding: "16px", margin: "8px", borderRadius: "8px" }}>
<h2>{name}</h2>
<p>{role}</p>
<div>
{skills.map((skill, i) => (
<Badge key={i} label={skill} color="#3b82f6" />
))}
</div>
</div>
);
}
function App() {
return (
<div>
<h1>Team</h1>
<UserCard name="Alice" role="Frontend Dev" skills={["React", "CSS"]} />
<UserCard name="Bob" role="Backend Dev" skills={["Node", "SQL"]} />
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>What is the correct way to pass a number as a prop to a component?