Components are the building blocks of React applications. They let us create independent, reusable pieces of code that we can combine to build complex user interfaces.
Think of components like LEGO blocks - each piece is self-contained and can be connected with other pieces to build something bigger.
Components are JavaScript functions that return pieces of UI. Some common examples include:
<Navbar />
- Navigation menu<Header />
- Page header<Avatar />
- User profile picture<Container>...</Container>
- Layout wrapper⚠️ Important: React component names must start with a capital letter. This is how React tells the difference between custom components and regular HTML elements.
// ❌ Bad: React will think this is an HTML element
function header() {
return <h1>Hello World</h1>;
}
// ✅ Good: React knows this is a custom component
function Header() {
return <h1>Hello World</h1>;
}
The modern way to create React components is using functions:
function Header(props) {
return (
<div>
<h1>Hello, {props.name}</h1>
</div>
);
}
Learn more about components in the React Component Lifecycle guide.
💡 Tip: Since React 16.8, we use hooks to add features like state management to functional components. While you might see older code using class components, functional components are now the recommended approach.
Components receive data through parameters called props
(short for properties). Props let parent components send data to their children:
// Passing a prop to our Header component
<Header name="CodePath" />
// The Header component using the prop
function Header(props) {
return <h1>Hello, {props.name}</h1>;
}
Props can include different types of data:
<Profile
name="CodePath" // String
age={25} // Number
isActive={true} // Boolean
user={{ id: 1, role: 'admin' }} // Object
onFollow={() => alert('Followed!')} // Function
/>
Props follow one important rule: A component must never modify its own props.
Think of props like arguments in a math function - the function uses the arguments but doesn't change them:
// ❌ Bad: Modifying props
function BadComponent(props) {
props.count = props.count + 1; // Don't do this!
return <div>{props.count}</div>;
}
// ✅ Good: Using props without modifying them
function GoodComponent(props) {
return <div>{props.count}</div>;
}
The below example shows how data flows from a parent component to a child component. The useState
hook is used to manage the state of the parent component.
function ParentComponent() {
const [count, setCount] = useState(0);
return (
<ChildComponent
count={count}
onIncrement={() => setCount(count + 1)}
/>
);
}
function ChildComponent(props) {
return (
<button onClick={props.onIncrement}>
Count: {props.count}
</button>
);
}
Learn more about React state management in the React useState Hook and React Expanded State Management guides.
Modern React uses hooks to manage component lifecycle events. The most common hooks are:
useState
- For managing component stateuseEffect
- For handling side effectsfunction UserProfile() {
// State management
const [user, setUser] = useState(null);
// Lifecycle management
useEffect(() => {
// This runs after component mounts
fetchUserData().then(data => setUser(data));
// This runs before component unmounts
return () => {
saveUserData(user);
};
}, []);
if (!user) return <div>Loading...</div>;
return <div>Welcome, {user.name}!</div>;
}
Learn more in the React Component Lifecycle guide.