React FundamentalsPart 1

What Is React? — Declarative UI and the Idea of Components

What problem did React set out to solve, and why does the shift 'from imperative to declarative' matter so much? A look at React's core idea, framed against your web-development experience.

If you’ve done any web development at all, the name React is familiar. It shows up in job posts, in tutorials, in other people’s dependency lists. And yet, when someone asks “what is React?”, most of us stall out somewhere around “uh… a frontend framework?”

This series walks through React’s core concepts framed against your web-development experience. It assumes you’ve already built something with HTML, CSS, and JavaScript, and it tells the story in the shape of “the old way was awkward here — React solves it like this.” As a first step, today we look at what React actually showed up to solve.


React is a ‘library’, not a ‘framework’

First, a small but important distinction. React introduces itself as “a library for building user interfaces.” The word library rather than framework is the key: it means React doesn’t decide everything — like routing or data management — for you.

React is responsible for exactly one thing: drawing the view. Changing pages based on the URL, talking to a server, managing global state — those you handle by picking and combining separate libraries. That makes React lightweight, but it also leaves “how to assemble it” up to you. Keep this trait in mind and the many options that appear later will make far more sense.


From imperative to declarative

The fastest way to understand React is to grab hold of one word: declarative. What that means becomes clear when you compare it to the old way.

Say we’re building a screen where “pressing a button increases a number by 1.” The old way, we did roughly this:

let count = 0;
const el = document.querySelector('#count');
button.addEventListener('click', () => {
  count += 1;
  el.textContent = count; // fix the screen 'directly'
});

Here the developer’s job is to spell out, step by step, “the value changed, so go fix this part of the screen like so.” This is imperative. As screens grow complex, the number of “if this changes, fix that” cases explodes — and this is where most bugs are born.

React flips the idea. Instead of writing the procedure for fixing the screen, the developer only declares “when the state is this, the screen looks like this.”

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

When count changes, React works out where and how to update the screen. The developer only writes the relationship: “if the state is this, the result is that.” As a cooking analogy: if imperative is a recipe’s step-by-step (“put the pot on the heat, stir after three minutes”), declarative is closer to handing over a photo of the finished dish.


Components — the screen as assemblable units

The second core idea is the component. Like Counter above, in React you define a piece of the screen as a single function. That function returns a screen (more precisely, a blueprint for drawing one), and we combine these pieces like Lego blocks to build the whole.

function App() {
  return (
    <div>
      <Header />
      <Counter />
      <Footer />
    </div>
  );
}

A well-built Counter can be reused in many places, and each piece only has to answer for what happens inside itself. This view of the screen — not as one giant document but as a composition of small parts — is actually a shared language across modern frameworks like Vue and Svelte too, not just React.


How React updates the screen as little as possible

If “when state changes, redraw the screen” is the rule, you might worry: isn’t redrawing the whole thing every time slow? This is where the Virtual DOM comes in.

React doesn’t touch the real screen (the DOM) directly. Instead it keeps a copy of the screen’s shape as a lightweight JavaScript object, and when state changes it compares the new version with the previous one, picks out only the parts that actually differ, and applies those to the real DOM. This comparison process is called reconciliation. Thanks to it, we get to write code the easy way — “re-declare the whole thing” — while actual screen updates stay minimal.

You don’t need to know this deeply right now. Just carry the sense that “React figures out the difference between what I declared and the current screen, and fills the gap itself,” and the coming discussions of State and rendering will follow much more naturally.


What this series covers — and React Native

To sum up, React’s idea is three sentences. Declare the screen as a function of state. Assemble the screen from reusable components. Let React minimize the actual updates. In the articles ahead, we’ll lay concepts like JSX, Props, State, useEffect, and Context onto this idea one at a time.

One thing to flag in advance: Part 1 of this series covers React on the web. React Native, so often mentioned in the same breath, takes the very way of thinking we just described and moves it from the web onto native mobile screens — and we’ll cover it in a separate Part 2. Understand React properly and React Native becomes a story told on top of it, and far easier for it. So for now, let’s start by getting comfortable with this sense of declarative.