Your first React page
What React actually does — build the page from a function — and the three lines that put the first component on screen.
What React is for
React is a library for building a page out of small functions. You describe what the screen should look like for a given piece of data, and React works out what has to change when that data changes. You never touch the page element by element again — you change the data, and the picture follows.
That is the whole idea, and everything else in this course is a detail of it. The page the reader sees is called the component tree, the functions are components, and the data they are given is props and state — two words worth meeting now, because they are the rest of the course.
The root, and the mount
React needs one element to live in: an empty <div id="root"></div> in the HTML. ReactDOM.createRoot takes that element and returns the React root; root.render(<App />) puts your component inside it. Everything the page shows comes from that one call.
The HTML file is boring on purpose: a title, the empty div, and a <script> that loads your .jsx file. All the interesting work is in the component, which is exactly the trade the library makes — markup is generated, not written.
A component is a function
A component is a function whose name starts with a capital letter and whose result is what should be on screen: function App() { return <h1>Hello</h1>; }. That <h1> looks like HTML but is not — the browser never sees a tag, because the JSX is turned into React.createElement calls before it runs. What comes out is an ordinary JavaScript value that describes an element.
Curly braces in the JSX are a window back into JavaScript: <h1>Hello, {name}!</h1> inserts the value of the variable name. Everything outside the braces is markup, everything inside is a normal JavaScript expression — that mix is what makes JSX worth learning.
The page is a tree, and React compares two of them
Every component returns elements, and some of those elements are other components. App returns a <Header />, React calls Header, and Header returns its own markup. The shape that comes out is a tree, and React keeps it as one so that it can compare two versions of it later.
The comparison is by position and type: a <Header /> in the same place under the same parent is treated as the same component, so its state survives a render. Move it under a different parent and React builds it again from scratch. That rule is why the tree is worth thinking about from the first page.
Nothing in the tree is drawn twice: each element describes one node, and a component that appears twice in the markup is two separate instances with separate state.
The smallest React page
// index.html holds <div id="root"></div> and loads this file.
const root = ReactDOM.createRoot(document.getElementById('root'));
function App() {
const name = 'React';
return (
<main>
<h1>Hello, {name}!</h1>
<p>This page was built from a function.</p>
</main>
);
}
root.render(<App />);What happens when you call render
root.render(<App />) does not paste markup into the div. React calls App, receives the element tree the function returned, and only then creates the DOM nodes that match it. A component is a description; the DOM is React's interpretation of it.
On a later update React builds a fresh description and compares it with the previous one, then changes only what differs. That comparison is why you never write document.querySelector in a React page: the description is the source, and the page follows it.
Where the globals come from
index.html loads App.jsx with a plain script tag. Before the file runs, the lesson runner turns the JSX into React.createElement calls, and the page already carries the React and ReactDOM globals. That is why the file starts with const root = ... and imports nothing.
A project made with a build tool would write two import lines instead, and the same two objects would arrive. What does not change is the order: React must exist before ReactDOM, the div must exist before createRoot looks for it, and the component must be defined before render is called.
Three ways the first render fails: passing the component itself — root.render(App) — instead of an element, <App />; calling createRoot with null because the script ran before the div existed; and writing the component name in lowercase, which React reads as an unknown tag. Each gives a blank page and a console message, so read the console first.
Try these next
- Render a second component under
<App />and give it a heading of its own. - Move the
<script>tag into the head and predict what happens before you run it. - Replace
{name}with a calculation, such as{2013 + 10}, and check the output.
Run it, then make it yours
Press Run and read the page and the console. Then change the greeting, add a second paragraph of your own, and rename the component — remembering to rename it in the render call too.
A page that calculates
Run it, then change the founding year and add one more computed line — a difference, a sum, or a percentage. Keep every value inside the component so the render stays a description.
The name has to start with a capital letter. App is treated as your component; a lowercase app would be treated as an unknown HTML tag and rendered as one.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What does createRoot need before it can render anything?
