Components
A component is a reusable piece of UI with its own markup and logic. A navigation bar, a product card, a search box and a whole checkout page can each be a component. You build small components and put them together to make bigger ones.
In this lesson you will write function components, nest them inside each other, move them into separate files with export and import, and learn the most important rule of all: components must be pure.
Your first component
A React component is a JavaScript function that returns JSX. Two rules make it a component instead of an ordinary function:
- Its name starts with a capital letter, such as
MenuItem. - You use it like a tag:
<MenuItem />.
import { createRoot } from "react-dom/client";
function Header() {
return (
<header>
<h1>Kabir's Dhaba</h1>
<p>Highway 9, near Rohtak bypass</p>
</header>
);
}
function MenuItem() {
return <li>Paneer paratha with curd</li>;
}
function Menu() {
return (
<section>
<h2>Breakfast</h2>
<ul>
<MenuItem />
<MenuItem />
<MenuItem />
</ul>
</section>
);
}
function App() {
return (
<>
<Header />
<Menu />
<footer>Open 6 am to 11 pm, every day</footer>
</>
);
}
createRoot(document.getElementById("root")).render(<App />);App is the top component. It renders Header and Menu, and Menu renders MenuItem three times. This structure is called the component tree. React starts at the root (App) and calls each component function to find out what to show.
Right now every MenuItem shows the same dish. In the next lesson, Props, you will pass different data to each copy.
Why the capital letter matters
JSX uses the first letter to decide what a tag means. A lowercase tag such as <header> or <li> is a built-in HTML element. A capitalised tag such as <Header> is your component. If you name a component menuItem and write <menuItem />, React treats it as an unknown HTML tag and your function never runs.
You can write components as function declarations or as arrow functions; both work the same:
function Badge() {
return <span className="badge">New</span>;
}
const Discount = () => <span className="badge">10% off</span>;A component can also return null to show nothing. You will use that in conditional rendering.
One component per file
Real projects keep each component (or a few small related ones) in its own file. Use export default for the main component of a file and import it where you need it:
// src/components/MenuCard.jsx
export default function MenuCard() {
return (
<article className="menu-card">
<h3>Chole bhature</h3>
<p>₹120</p>
</article>
);
}
// src/App.jsx
import MenuCard from "./components/MenuCard.jsx";
export default function App() {
return (
<main>
<MenuCard />
<MenuCard />
</main>
);
}A file can also have named exports such as export function Price() {...}, which you import with braces: import { Price } from "./Price.jsx";. A common habit is one default export per component file, named the same as the file. The Try-it editor runs a single file, so the examples in this course keep all components together.
Do not define components inside components
Always define components at the top level of a file. This looks harmless, but it is a bug:
function Menu() {
// Wrong: a new MenuItem function is created on every render of Menu
function MenuItem() {
return <li>Masala chai</li>;
}
return <ul><MenuItem /></ul>;
}Every time Menu renders, it creates a brand-new MenuItem function. React sees a "different" component each time, throws away the old one and builds it again from scratch. This is slow, and it wipes any state inside MenuItem, such as text typed into an input. Move MenuItem outside Menu and pass it data through props instead.
Keep components pure
A pure function always returns the same result for the same inputs and does not change anything outside itself. React expects every component to be pure while it renders: given the same props and state, it must return the same JSX, and it must not modify variables, objects or the DOM that existed before the render.
Why does this matter? React may call your component many times: when its parent updates, in Strict Mode during development, or while preparing an update in the background. If rendering changes something outside the component, the result depends on how many times React happened to call it. Watch this impure component:
import { useState } from "react";
import { createRoot } from "react-dom/client";
let nextToken = 0; // a variable outside the component
function Token() {
nextToken = nextToken + 1; // impure: changes an outside variable while rendering
return <li>Token number {nextToken}</li>;
}
function Queue() {
const [refreshes, setRefreshes] = useState(0);
return (
<>
<ul>
<Token />
<Token />
<Token />
</ul>
<button onClick={() => setRefreshes(refreshes + 1)}>Refresh screen ({refreshes})</button>
</>
);
}
createRoot(document.getElementById("root")).render(<Queue />);The first render shows tokens 1, 2 and 3. Click the button: nothing about the queue changed, yet the tokens become 4, 5 and 6. The screen now depends on how many times React rendered, which is exactly the kind of bug purity prevents. The fix is to pass each token number in as data:
import { createRoot } from "react-dom/client";
function Token({ number }) {
return <li>Token number {number}</li>;
}
function Queue() {
return (
<ul>
<Token number={1} />
<Token number={2} />
<Token number={3} />
</ul>
);
}
createRoot(document.getElementById("root")).render(<Queue />);Creating and changing local variables inside a component is fine, because they are new on every render. What you must avoid during rendering is changing things that already existed. Side effects such as timers, network requests and changing the document title belong in event handlers or effects, which you will learn in Handling Events and useEffect & Side Effects.
Common mistakes
- Lowercase component names.
function card()used as<card />is treated as an HTML tag. Start names with a capital letter. - Calling a component like a function. Write
<MenuItem />, not{MenuItem()}. The tag form lets React manage the component's state and lifecycle. - Nesting component definitions. Defining a component inside another one resets its state on every render.
- Changing outside data while rendering. Counters, arrays or objects declared outside the component must not be modified inside its body.
Key points
- A component is a function whose name starts with a capital letter and which returns JSX.
- Use components as tags (
<Header />) and nest them to build a component tree. - Keep each component in its own file and use
export defaultandimportto share it. - Define components at the top level, never inside another component.
- Components must be pure: same props and state give the same JSX, with no outside changes.
Exercise
Build a small "college notice board". Write a Notice component that returns a list item, a NoticeBoard component that shows a heading "Notices for BCA students" and three Notice items, and an App component that renders NoticeBoard and a footer with the college name. Use a fragment in App.
Show solution
import { createRoot } from "react-dom/client";
function Notice() {
return <li>Internal exams start on 16 November.</li>;
}
function NoticeBoard() {
return (
<section>
<h2>Notices for BCA students</h2>
<ul>
<Notice />
<Notice />
<Notice />
</ul>
</section>
);
}
function App() {
return (
<>
<NoticeBoard />
<footer>Government College, Lucknow</footer>
</>
);
}
createRoot(document.getElementById("root")).render(<App />);Each component is defined at the top level and used as a tag. In the next lesson you will use props so that each Notice can show different text.
Quick Quiz
1. Which name can be used as a React component?
Component names must start with a capital letter; lowercase tags are treated as HTML elements.
2. What is wrong with defining a component inside another component?
React sees a different function each render, so the inner component is thrown away and recreated.
3. What does it mean for a component to be pure?
Pure components make rendering predictable, no matter how many times React calls them.
4. How do you share a component from another file?
Components are ordinary JavaScript functions, so ES module export and import share them.
Learn React with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
