Skip to solution
easyFrontend

What are the advantages of using React over plain JavaScript?

808 views
01

Understand the problem

Question presented to candidate: "We could build this UI with plain JavaScript and document.querySelector. Make the case for React — and be honest about what it costs."

What a strong answer should cover:

  • The central win: declarative rendering eliminates the class of bugs where the DOM and the data drift out of sync.
  • Componentisation — reusable units that own their own state and markup together.
  • Reconciliation — React computes the minimal DOM updates so you never hand-write them.
  • Ecosystem and hiring — routing, forms, data fetching, testing tools, and a large talent pool.
  • Cross-platform — the same component model targets native via React Native.
  • Honest costs: a build step, bundle size, a learning curve, and no advantage for genuinely simple pages.
  • Maturity signal: React is not automatically faster than hand-written DOM code; it trades a little raw speed for correctness and maintainability.

Clarifying questions expected:

  • "How complex is the UI — how much state is there, and how much of it is shared?"
  • "Is this a long-lived product with a team, or a one-off page?"

Code / implementation expected: Optional. A side-by-side of the same widget in both styles makes the argument faster than prose.

benefitsdeclarativecomponentsvirtual dom
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for React interviews — assumes JavaScript and DOM basics. Difficulty: Easy to Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. This is a trade-off question, so the answer below deliberately

Solution ready — 2 min read

Classified // press E to declassify

04

Explore the playground snippets

The same widget, imperative versus declarative, side by side
Run Playground
import { useState, useRef, useEffect } from "react";

// ── The imperative way, written the way plain JS forces you to ──────────────
// Every derived piece of UI needs its own explicit update. Miss one and the
// widget contradicts itself — and nothing tells you which line went stale.
function ImperativeCounter() {
  const rootRef = useRef(null);
  const scoreRef = useRef(0);

  useEffect(() => {
    const root = rootRef.current;
    root.innerHTML =
      '<p>Score: <b class="score">0</b></p>' +
      '<p class="status">untouched</p>' +
      '<p class="trophy" style="display:none;color:goldenrod">🏆 three or more!</p>' +
      "<button>Score a goal</button>";

    const btn = root.querySelector("button");
    const onClick = () => {
      scoreRef.current += 1;
      const n = scoreRef.current;
      // Four separate, easily-forgotten DOM edits for ONE state change:
      root.querySelector(".score").textContent = String(n);
      root.querySelector(".status").textContent = n > 5 ? "getting high" : "counting";
      root.querySelector(".trophy").style.display = n >= 3 ? "block" : "none";
      btn.textContent = n >= 5 ? "Score another" : "Score a goal";
    };
    btn.addEventListener("click", onClick);
    return () => btn.removeEventListener("click", onClick);
  }, []);

  return <div ref={rootRef} />;
}

// ── The declarative way ────────────────────────────────────────────────────
// One state value. Every derived line follows from it automatically, so they
// cannot get out of step with each other.
function DeclarativeCounter() {
  const [score, setScore] = useState(0);

  return (
    <div>
      <p>Score: <b>{score}</b></p>
      <p>{score === 0 ? "untouched" : score > 5 ? "getting high" : "counting"}</p>
      {score >= 3 && <p style={{ color: "goldenrod" }}>🏆 three or more!</p>}
      <button onClick={() => setScore((s) => s + 1)}>
        {score >= 5 ? "Score another" : "Score a goal"}
      </button>
    </div>
  );
}

export default function App() {
  const box = { border: "1px solid #ccc", borderRadius: 8, padding: 16, flex: 1 };
  return (
    <div style={{ padding: 24, fontFamily: "system-ui" }}>
      <div style={{ display: "flex", gap: 16 }}>
        <div style={box}><h4 style={{ marginTop: 0 }}>Imperative</h4><ImperativeCounter /></div>
        <div style={box}><h4 style={{ marginTop: 0 }}>Declarative</h4><DeclarativeCounter /></div>
      </div>
      <p style={{ color: "#666", fontSize: 13 }}>
        Both behave identically. The left one needs four explicit DOM edits per
        click; the right one derives all four from a single number.
      </p>
    </div>
  );
}
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 10 of 119 decoded in the React.js track. One more won't hurt.

Back to track