React, also written React.js, is an open-source JavaScript library for building user interfaces from reusable components, in which developers describe what the interface should look like for a given state and the library updates the page when that state changes. In web applications it is one of the most widely used foundations for single-page applications, server-rendered sites and hybrid architectures.
React itself focuses on the view layer: components, rendering and state within components. Routing, data fetching conventions, server rendering setup and build tooling come from the surrounding ecosystem or from frameworks built on React, such as Next.js, which is why React is usually described as a library rather than a complete framework.
How React renders components
React renders by calling component functions that return a description of the interface, usually written in JSX, a syntax extension that looks like HTML inside JavaScript and compiles to function calls. Each call produces a tree of lightweight element objects. React compares the new tree with the previous one in a process called reconciliation and applies only the necessary changes to the real DOM.
Reconciliation relies on heuristics rather than a full tree diff. Elements of different types are replaced entirely, elements of the same type are updated in place, and lists are matched through the key prop. Stable, unique keys let React move existing items instead of recreating them; using array indexes as keys in reorderable lists causes lost input state and unnecessary work.
| Phase | What happens | Can it be interrupted |
|---|---|---|
| Trigger | State or props change, or a parent re-renders | Not applicable |
| Render | Component functions run and return new elements | Yes, with concurrent rendering |
| Commit | DOM changes are applied in one batch | No |
| Effects | Layout effects run, then passive effects after paint | No |
The internal architecture, known as Fiber, splits rendering into small units of work. This allows concurrent rendering, in which React can pause a low-priority update, handle urgent input first and resume later, using APIs such as startTransition and useDeferredValue.
State, props and hooks
Data in React flows one way, from parent to child, through props. A component that needs to remember something between renders stores it as state, and any state update schedules a re-render of that component and its descendants. Hooks are functions that let function components use state and other React features; they must be called in the same order on every render, which is why they cannot appear inside conditions or loops.
| Hook | Purpose | Typical pitfall |
|---|---|---|
| useState | Local state value and setter | Mutating objects instead of replacing them |
| useReducer | State with complex transitions | Overusing it for simple values |
| useEffect | Synchronizing with external systems | Missing or excessive dependencies |
| useContext | Reading shared values without prop drilling | Large contexts that re-render many components |
| useMemo and useCallback | Caching values and functions between renders | Adding them everywhere without measurement |
| useRef | Mutable value or DOM reference without re-rendering | Using it to bypass state that should drive the view |
A frequent design error is treating useEffect as a general place for logic. Effects are meant for synchronizing with systems outside React, such as subscriptions or network requests; values that can be computed from props and state during rendering should not be stored in state and updated through effects.
Rendering strategies with React
React supports several rendering strategies, and the choice shapes performance, search visibility and hosting. Pure client-side rendering builds the interface in the browser, while server-side rendering produces HTML on the server and then attaches interactivity through hydration. React Server Components, supported by some frameworks, run selected components only on the server and send their output to the client without shipping their code.
| Strategy | Where HTML is produced | Strength | Cost |
|---|---|---|---|
| Client-side rendering | Browser | Simple hosting, rich interactivity | Slower first content, weaker for crawlers |
| Server-side rendering | Server per request | Fast first content, fresh data | Server load and hydration cost |
| Static site generation | Build time | Very fast and cheap to serve | Data only as fresh as the last build |
| Server Components | Server, streamed | Less JavaScript sent to the browser | Requires a supporting framework |
Hydration is a common bottleneck. A large server-rendered page can look ready yet ignore input until hydration finishes, which harms responsiveness metrics such as INP. Streaming and selective hydration reduce the problem by hydrating visible or interacted parts first.
React compared with Vue.js, Angular and Svelte
React differs from neighboring frontend tools mainly in scope and reactivity model. It re-runs component functions and reconciles output, while Vue.js and Svelte track dependencies so that only affected parts update. Angular is a complete framework with built-in routing, dependency injection and forms.
| Technology | Type | Reactivity approach | Templating |
|---|---|---|---|
| React | UI library | Re-render and reconcile | JSX |
| Vue.js | Progressive framework | Fine-grained reactive proxies | HTML-based templates or JSX |
| Angular | Full framework | Change detection and signals | HTML templates |
| Svelte | Compiler-based framework | Compiled updates | HTML-like components |
React’s main practical advantages are its large ecosystem, a big hiring pool and the option to target native mobile apps through React Native with a similar component model. Its main costs are the need to assemble a stack and the risk of excess re-renders in large component trees.
Common mistakes and performance pitfalls
- Unstable keys in lists cause lost focus, wrong input values and slow updates.
- State placed too high forces large subtrees to re-render on every keystroke; move state down or split components.
- Derived state in effects creates extra renders and inconsistent intermediate screens.
- Large client bundles delay interactivity; use code splitting with
React.lazyand route-level loading. - Premature memoization adds complexity; measure with the React Profiler before adding
memooruseMemo.
Most React performance problems are architecture problems rather than library limits. Keeping components small, colocating state with the components that use it and sending less JavaScript to the browser usually helps more than micro-optimizations.
In simple terms
React is a tool for building the interactive parts of websites and web apps. Developers do not give the browser a long list of small steps. Instead, they describe what the screen should look like in each situation.
When something changes, React works out what is different. Then it updates only the parts that changed. Think of labeled building blocks. Each block knows how to draw itself, and the same block can be reused across the whole app.
A practical example
A logistics company builds an internal dashboard where dispatchers track around 500 delivery vehicles. The interface consists of React components: a map, a filterable vehicle table, a detail panel and a notification list. Position updates arrive every few seconds over a WebSocket connection.
The first version keeps all data in a single top-level state object, so every position update re-renders the whole dashboard and typing in the filter field feels sluggish. The team moves vehicle data into a dedicated store, gives each table row a stable key based on vehicle ID, and wraps the filter result in useDeferredValue so typing stays responsive while the table catches up.
After the change, the React Profiler shows that only affected rows and map markers re-render, and dispatchers report that the filter responds instantly even during peak hours.