Hirefullstack – Software Engineering & IT-Beratung aus Berlin
← Back to overview
Beginner 12 min read

React from zero

The six words you need before any of it makes sense

In one sentence

Component, JSX, props, state, render, hook – once these six words sit, the rest of React is detail work.

You know JavaScript. What you are missing is the language React uses to talk about itself. Here are the six words that turn up in every explanation – each in two sentences.

Tip How to read this tutorial

Words with a dashed underline can be clicked – the explanation appears right there. And anything folded away under “In more depth” can safely be skipped on a first pass.

1. Component = a function describing an interface

A ComponentA function that describes what a piece of the interface should look like – a button, or a whole page.It always starts with a capital letter and returns JSX. You then use it like your own HTML element: <MyButton />. is a perfectly ordinary JavaScript function. The special part: it does not return a number or a string, but a description of what should appear on screen.

Welcome.tsx
function Welcome() {
  return <h1>Hello!</h1>;
}

// You use it like your own HTML element:
<Welcome />
Careful The capital letter is mandatory

<Welcome /> is your component; <welcome /> would be an unknown HTML element to React. The first letter decides.

2. JSX = HTML living inside JavaScript

The line <h1>Hello!</h1> in the middle of your code is called JSXThe HTML-looking syntax sitting inside your JavaScript, lines like <p>Hello</p>.It is not real HTML. A build tool turns it into ordinary function calls before anything runs.. It looks like HTML but it is JavaScript: a build tool turns it into ordinary function calls before anything runs.

jsx.tsx
const name = "Ada";
const isAdmin = true;

<div className="card">           {/* class is called className here */}
  <h1>Hello, {name}!</h1>         {/* curly braces = JavaScript */}
  <p>{2 + 3} messages</p>         {/* any expression works */}

  {isAdmin && <button>Delete</button>}      {/* condition */}
  {isAdmin ? <p>Boss</p> : <p>Guest</p>}    {/* if / else */}
</div>
Inside curly braces anything that produces a value is allowed – but no if statement and no for loop.
Good to know Lists are built with map

Since there is no for in JSX, you build lists with map: {names.map(n => <li key={n}>{n}</li>)}. We will get to that key in a moment.

3. Props = the arguments of a component

PropsThe values a component receives from the outside – like the arguments of a function.Short for “properties”. They come in from above and must not be changed by the component. are the values a component receives from outside. You write them like HTML attributes, and the function receives them as one object.

props.tsx
function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>;
}

// It is more common to unpack the object straight away:
function Greeting({ name, loud }) {
  return <h1>Hello, {name}{loud ? "!!!" : "."}</h1>;
}

<Greeting name="Ada" loud />
<Greeting name="Grace" />
Pitfall Props are reading material, not a notebook

A component must never change its own props. They belong to whoever passed them in. Anything that should change is state – which is next.

4. State = a component's memory

A normal variable inside a component is gone after the next pass. StateA value a component remembers and is allowed to change – the text in an input field, for example.When state changes, React redraws the component. That is exactly what separates it from a normal variable. is the value React keeps for you – and when you change it, React redraws the component.

nothing happens on screen
function Counter() {
  let count = 0;

  return (
    <button onClick={() => count++}>
      {count}
    </button>
  );
}
this is how React notices
function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
      {count}
    </button>
  );
}

On the left count does briefly go up – but nobody tells React, and on the next pass everything starts at 0 again. On the right React knows about the change and redraws.

Put another way

Picture React as an illustrator. A normal variable is a thought they immediately forget. useState is their notebook: whatever is written there survives – and the moment you write in it, they redraw the picture.

5. Render = React calls your function

A RenderReact calls your component function and looks at what it returns. Nothing more happens yet.The result is a description (“this is how it should look”). Only afterwards does React decide what actually changes on the page. is nothing mysterious: React calls your component function and looks at what comes back. Then it compares that result with the previous one and changes only the differences in the browser.

sequence.txt
You click the button

setCount(1)  – React notes: "something changed here"

React calls Counter() again              ← this is the render

Compare results: "the 0 has to become a 1"

Change just that one number in the browser
Good to know “Re-renders” sound worse than they are

A Re-renderReact calls the component function again because something changed.That does not mean the page is rebuilt. If the result is the same as before, nothing changes in the browser at all. simply means the function runs again. If the result is the same as before, nothing on the page changes at all.

6. Hook = a borrowed ability

A function on its own cannot remember anything. A HookA built-in function whose name starts with “use” and that lends your component an ability – such as remembering something.Hooks may only appear at the top level of a component, never inside an if or a loop. lends it exactly such an ability: useState the remembering, useEffect reacting to the outside world, useRef a silent note. Every hook starts with use.

rules.txt
Two rules – these always apply:

1. Hooks go at the very top of the component.
   Not inside an if, not in a loop, not after a return.

2. Hooks only live in components (capital letter)
   or in your own hooks (name starts with use).
Pitfall Why these rules?

React keeps track of your hooks by their order, not their name. If one is skipped on the second pass, the whole list shifts – and your counter suddenly holds the value of the text field.

All of it together

Everything.tsx
import { useState } from "react";

// A component that receives a prop
function Greeting({ name }: { name: string }) {
  return <p>Hello, {name}!</p>;
}

export default function App() {
  // State: the text somebody types
  const [name, setName] = useState("World");

  return (
    <div>
      <input
        value={name}                                  // driven by state
        onChange={(e) => setName(e.target.value)}     // typing changes state
      />
      <Greeting name={name} />                        {/* pass the prop on */}
    </div>
  );
}
Typing → setName → React calls App again → Greeting receives the new name → the paragraph changes.
In more depth: what is a “controlled input”? optional

In the example above the <input> carries both value and onChange. That is called a controlled field: not the browser decides what is in it, but your state.

controlled.tsx
// controlled: state is the source of truth
<input value={name} onChange={(e) => setName(e.target.value)} />

// uncontrolled: the browser keeps the value itself
<input defaultValue="World" />

The sequence is a small circle: you type → onChange fires → setName changes the StateA value a component remembers and is allowed to change – the text in an input field, for example.When state changes, React redraws the component. That is exactly what separates it from a normal variable. → React redraws → the field shows the new value. It feels like typing straight into the field; in reality React takes the detour through state.

Pitfall value without onChange

If you write value={name} and forget onChange, nothing can be typed into the field – the state never changes. React warns about this in the console.

Does it stick?

6 questions on this lesson. Wrong answers show up in your stats.

Now write it yourself

Your first component

Build a greeting: whatever someone types into the field should appear right below it. You need exactly what was covered above – a prop, a state and a controlled input.

  • Greeting shows Hello, <name>! – the name arrives as a prop
  • Typing in the field updates the greeting immediately
  • The field starts out containing World
import { useState } from "react";

// TODO: accept the "name" prop and output "Hello, <name>!"
function Greeting(props: { name: string }) {
  return <p data-testid="greeting">Hello, ???</p>;
}

export default function App() {
  // TODO: add state, starting value "World"

  return (
    <div style={{ fontFamily: "system-ui", padding: 16 }}>
      <input aria-label="name" />
      <Greeting name="???" />
    </div>
  );
}

Hirefullstack

Need React firepower on your team?

We have been building React and Next.js applications for clients across Germany for years – as a single expert, as reinforcement for an existing team, or as a complete Scrum team.

Talk about your project →