#Function components
A component is a JavaScript function that takes one argument — an object of props — and returns what to render: JSX, a string, a number, null, or an array of those. Components are how you split a UI into pieces you can name, reuse and reason about one at a time. <Greeting name="Rohit" /> reads like an HTML tag, but it means "React, call Greeting with { name: "Rohit" } and put whatever it returns here".
The mental model: a component is a recipe, and React is the cook. You write the recipe once; React decides when to follow it (on first render and whenever its inputs change) and what to do with the dish. You never call the recipe yourself, and a recipe never reaches into the kitchen to change things — given the same ingredients it produces the same dish. That last part is React's purity rule: rendering must be pure. Side effects (requests, timers, DOM changes) belong in event handlers and effects, not in the function body.
function Avatar({ name, size }) {
return (
<img
src={`/avatars/${name}.png`}
alt={name}
width={size}
height={size}
/>
);
}
export function Greeting({ name }) {
return (
<div className="greeting">
<Avatar name={name} size={40} />
<p>Hello, {name}!</p>
</div>
);
}
export function App() {
return (
<>
<Greeting name="Rohit" />
<Greeting name="Asha" />
</>
);
}
// <App /> renders:
// <div class="greeting"><img alt="Rohit" width="40" height="40" src="/avatars/Rohit.png"><p>Hello, Rohit!</p></div>
// <div class="greeting"><img alt="Asha" width="40" height="40" src="/avatars/Asha.png"><p>Hello, Asha!</p></div>- React calls
App()with an empty props object. It returns twoGreetingelements — descriptions, not calls. Nothing insideGreetinghas run yet. - React then calls
Greeting({ name: "Rohit" }). The parameter is destructured, sonameis"Rohit". It returns adivcontaining anAvatarelement and ap. - React calls
Avatar({ name: "Rohit", size: 40 }), which returns animgelement. Built-in elements likeimgare the leaves: React turns them into DOM nodes. - The same happens for
"Asha". The twoGreetings are separate instances: ifGreetinghad state, each would have its own copy. - The result is a tree:
App→ twoGreetings → each anAvatarand ap. Components compose like functions do, and each one only knows about its own props.
The rules every function component follows:
- Name starts with a capital letter. JSX compiles
<Greeting />to a reference to theGreetingvariable but<greeting />to the string"greeting". A lowercase component renders an unknown HTML element instead, and React warns: "The tag <greeting> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter." - Returns one thing: one element (use a fragment for siblings),
nullfor nothing, a string or an array. - Is pure during render: no fetches, no
document.title = …, no changing variables outside the function. Compute from props and state; do side effects in handlers or effects. - Is defined at the top level of a module, never inside another component (gotcha below).
{Counter()} instead of <Counter /> "works" until it doesn't. Calling it directly runs it as part of the parent's render, so its useState becomes one of the parent's hooks. With a condition, {show && Counter()}, hiding it changes how many hooks the parent calls, and React 19.3 throws: "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." With <Counter />, React creates a separate instance with its own hooks, and showing or hiding it is just a mount or unmount (see Rules of hooks).