The biggest change React brings is not new syntax but a new way to think about updates. In plain JavaScript you change the page by finding elements and editing them. In React you describe what the page should show for a given state, and React updates it for you.
This is the difference between imperative and declarative code. If you have not seen how React updates the page, the guide on what React is sets the foundation.
The difference at a glance
| Plain JavaScript | React | |
|---|---|---|
| Approach | Imperative | Declarative |
| You write | Steps to change the DOM | A description of the UI |
| Updates | Manual | Automatic from state |
| Reuse | Functions or templates | Components |
Plain JavaScript gives you full control and no build step. React gives you automatic updates and reusable components, at the cost of a build tool.
The same counter in plain JavaScript
Start with a page that holds a single button:
<button id="countButton">Count: 0</button>The button text itself shows the current count, so the JavaScript only needs to find and update this one element.
Now write the JavaScript that makes it count:
const button = document.getElementById("countButton");
let count = 0;
button.addEventListener("click", () => {
count = count + 1;
button.textContent = "Count: " + count;
});This works, but it mixes three concerns in one place: finding the element, tracking the number, and writing the new text. Every feature you add means more code that manually finds nodes and keeps them consistent.
The same counter in React
In React the same counter is a component:
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
const increment = () => setCount((previousCount) => previousCount + 1);
return <button onClick={increment}>Count: {count}</button>;
}You never call textContent or look up an element. You declare that the button shows the current count, and you tell React to update the count when clicked. React rebuilds the description and changes only the button text.
The updater function passed to setCount receives the latest count, which is the reliable way to write an update that depends on the previous value.
What React removes from your code
The plain version has three jobs mixed together:
- Select the element you want to change.
- Store the current value somewhere.
- Apply the new value to the element.
React keeps the last two jobs and removes the first. You store the value in state, describe how it appears in JSX, and React finds and updates the matching DOM node. That removal is the core of the Virtual DOM and reconciliation process.
Which one should you use
Plain JavaScript is the right choice for a small interaction on a mostly static page. If a page needs one button and nothing else, a script tag is simpler than a build tool.
React becomes the better choice as the interface grows. When many controls share state, or the same UI repeats across pages, the imperative version becomes hard to keep consistent. React's declarative model pays for its setup cost at that point.
You do not have to choose once forever. React can be added to an existing page gradually, so a plain JavaScript site can adopt it one piece at a time.
What to learn next
To see the declarative model in action, build the counter yourself with the guide on your first React component. Then learn how React turns state into efficient DOM updates in the Virtual DOM guide.
Rune AI
Key Insights
- Plain JavaScript updates the DOM imperatively with direct commands.
- React updates the DOM declaratively from state.
- In React you describe the result instead of listing every step.
- React keeps the visible UI and your data in sync.
- Both use the same underlying JavaScript and DOM.
Frequently Asked Questions
Is React a different language from JavaScript?
Do I need plain JavaScript after learning React?
Can I mix plain JavaScript with React?
Conclusion
Plain JavaScript updates the page imperatively, by finding elements and changing them one at a time. React updates the page declaratively, by describing what the UI should look like for a given state. The difference is the main reason teams adopt React.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.