Home/Learn/React/The Mental Model — UI as a Function of State

The Mental Model — UI as a Function of State

Beginner
Fundamentals

You describe what the screen should look like for a given state, and React works out what to change. You never write the change itself — that inversion is the whole framework.

Overview

Every UI approach before React was imperative: find the element, change its text, add a class, remove a row. That works until there are twelve pieces of state and forty places that touch the DOM, at which point the UI and the data drift apart and nobody can say why. React replaces it with one rule — given this state, the screen looks like this — and takes responsibility for the transitions. Your job becomes deciding what state exists and what it renders to. If you find yourself reaching for the DOM directly, that is almost always the signal that some piece of state is missing.

Imperative vs Declarative

The same feature written both ways. Notice that the declarative version has no instructions about changing anything.

Describe the destination, not the journey
// Imperative — you perform each transition yourself
function showResults(results) {
  spinner.style.display = 'none'
  errorBox.style.display = 'none'
  list.innerHTML = ''
  results.forEach(r => list.append(makeRow(r)))
  emptyState.style.display = results.length ? 'none' : 'block'
}
// Every new state means auditing every branch again.

// Declarative — you describe the destination for each state
function Results({ status, results, error }) {
  if (status === 'loading') return <Spinner />
  if (status === 'error')   return <ErrorBox message={error} />
  if (results.length === 0) return <EmptyState />
  return <ul>{results.map(r => <Row key={r.id} {...r} />)}</ul>
}
// Add a state and the compiler and the reader both see the gap.

One-Way Data Flow

Data goes down through props, changes come back up through callbacks. There is no two-way binding in React, deliberately.

Props down, callbacks up
function ProblemList() {
  const [selected, setSelected] = useState(null)      // state lives here

  return (
    <>
      {problems.map(p => (
        <ProblemRow
          key={p.id}
          problem={p}                       // data flows DOWN
          isSelected={p.id === selected}
          onSelect={setSelected}            // changes flow UP
        />
      ))}
      <Detail problemId={selected} />       // the same state, read again
    </>
  )
}

// A child never reaches into a parent and never mutates a prop.
// Because there is exactly one owner of each piece of state, you can
// always answer "who changed this?" by looking at one component.

What Actually Ships

The landscape you are joining in 2026, so the terminology in job descriptions makes sense.

React, and the stack around it
// React itself renders components. It does not include:
//   routing        -> React Router, or a framework's own router
//   data fetching  -> TanStack Query, or a framework's loaders
//   a build        -> Vite, or Next.js

// So real jobs say "React" and mean React plus a stack around it.

// Two ways teams start a project today:
//   Vite + React        a single-page app, you own the server story
//   Next.js             routing, server rendering and data built in

// Class components still exist in older codebases and you should be
// able to read them, but everything new is function components and
// hooks. This track is hooks throughout.

// React 19 added Server Components, Actions and the use() hook.
// They matter most inside a framework, so they appear in the
// Next.js track rather than here.

Key Points to Remember

  • 1React is declarative: you describe the UI for a given state and React performs the DOM changes
  • 2Reaching for the DOM directly is usually a sign that a piece of state is missing
  • 3Data flows down through props and changes flow up through callbacks — there is no two-way binding
  • 4Each piece of state has exactly one owner, which is what makes changes traceable
  • 5React is only the rendering layer; routing, data fetching and the build come from the surrounding stack

Interview Questions

Sign in to ask Aria
1

What does it mean that React is declarative rather than imperative?

Easy
2

Why does React use one-way data flow instead of two-way binding?

Medium
3

If you find yourself calling document.querySelector inside a component, what has usually gone wrong?

Medium

Ask Aria about The Mental Model — UI as a Function of State

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…