Skip to content
Home
React Guide: Complete Reference for Modern Frontend Development

React Guide: Complete Reference for Modern Frontend Development

React React 9 min read 1711 words Intermediate ExcellentWiki Editorial Team

React, maintained by Meta and a community of individual contributors, is the most widely adopted front-end library for building user interfaces. According to the State of JS survey, React has held the highest satisfaction and usage ratios among front-end frameworks for several consecutive years. Unlike full-featured frameworks such as Angular or Vue, React describes itself as a library for building composable user interfaces. It provides the view layer of an application and leaves concerns like routing, state management, and HTTP requests to the surrounding ecosystem.

Why React Dominates Front-End Development

React’s component-based architecture encourages developers to break complex UIs into small, reusable pieces. Each component encapsulates its own structure, logic, and styling, making code easier to reason about and test. As Dan Abramov, co-author of Redux and Create React App, explained in his blog post “The Elements of UI Engineering,” the component model forces developers to think in terms of state transitions rather than DOM manipulations, which drastically reduces bugs in complex interfaces.

Facebook introduced React in 2013 to solve the problem of maintaining consistent state across a rapidly growing social network. The key innovation was the virtual DOM — a lightweight JavaScript representation of the real DOM. When state changes, React computes a diff between the previous and next virtual DOM trees and applies only the minimal set of DOM mutations. This declarative approach means developers describe what the UI should look like for a given state, and React handles how to update the DOM efficiently.

Understanding the Virtual DOM

The virtual DOM is not a unique concept to React — similar ideas appear in Vue, Preact, and SolidJS — but React popularized it. When a component’s state changes, React creates a new virtual DOM tree and runs a reconciliation algorithm (often called “reconciler”) to compare it with the previous tree. This process, detailed in the React documentation under “Reconciliation,” uses a heuristic O(n) algorithm based on two assumptions: elements of different types produce different trees, and keys on list elements help identify stable items across renders.

React 18 introduced a new “concurrent” reconciler that can interrupt rendering to handle higher-priority updates, a feature described in the React RFC #213. This enables features like useTransition for marking non-urgent state updates and Suspense for declarative loading states. The concurrent reconciler is opt-in and backward-compatible, allowing teams to adopt it incrementally.

JSX: JavaScript Syntax Extension

JSX is a syntax extension that looks like HTML but compiles to JavaScript function calls. React recommends JSX for describing what the UI should look like, even though it is not required. Under the hood, JSX transforms into React.createElement calls (or jsx() in React 17+ with the new JSX transform). For example:

const element = <h1 className="greeting">Hello, world!</h1>;

compiles to:

const element = React.createElement('h1', { className: 'greeting' }, 'Hello, world!');

JSX prevents injection attacks by default because React DOM escapes any embedded values before rendering. The React team’s official documentation on JSX in Depth covers expression embedding, props defaults, and how JSX differs from HTML (className vs class, htmlFor vs for, camelCase event handlers).

Component Architecture Patterns

React components come in two historical flavors: class components (with lifecycle methods like componentDidMount, shouldComponentUpdate) and function components (with hooks since React 16.8). The React documentation explicitly recommends function components with hooks for all new code, and class components are considered a legacy API.

Composition over Inheritance

React’s component model strongly favors composition over inheritance. Instead of creating class hierarchies, you compose smaller components into larger ones. This pattern is documented in the React docs under “Composition vs Inheritance.” Common composition patterns include:

  • Containment: Using the children prop to pass nested elements
  • Specialization: Wrapping a generic component with a more specific one
  • Render Props: Passing a function as a prop to control rendering
  • Higher-Order Components: Functions that take a component and return an enhanced version

Thinking in Components

Dan Abramov’s article “Thinking in React” outlines a five-step process for building UIs with React: break the UI into a component hierarchy, build a static version, identify the minimal complete representation of UI state, determine where state should live, and add inverse data flow. This methodology remains the canonical approach for structuring React applications.

Hooks: The Modern React API

Hooks, introduced in React 16.8, let function components use state and other React features without writing a class. The most commonly used hooks are:

  • useState — Declares state variables in function components
  • useEffect — Performs side effects (data fetching, subscriptions, DOM manipulation)
  • useContext — Subscribes to React context without nesting
  • useRef — Creates mutable references that persist across renders
  • useMemo / useCallback — Memoizes values and functions to prevent unnecessary re-renders

The Rules of Hooks — documented in the React FAQ — require that hooks are called at the top level of a component (not inside loops, conditions, or nested functions) and only from React function components or custom hooks. These rules ensure that hooks are called in the same order on every render, which is essential for React to correctly associate state between renders.

Server Components and the Future

React Server Components (RSC), introduced in React 18 and adopted by Next.js 13+, represent a paradigm shift. Server Components run exclusively on the server, never on the client, and can directly access databases, file systems, and backend services. They reduce the JavaScript bundle size because Server Components are never sent to the client. The React RFC #188 details the design and motivation for RSC, emphasizing zero-bundle-size components and seamless integration with client components.

Handling Events in React

React’s event system normalizes cross-browser differences through SyntheticEvent, a wrapper around the native DOM event object. Event handlers are passed as camelCase props (onClick, onChange, onSubmit) and receive a synthetic event instance. React pools synthetic events for performance — the event object is reused after the callback completes, so accessing it asynchronously requires calling event.persist().

Event handling in React follows the delegation pattern: React attaches a single event listener at the root of the React tree and maps events to the correct component handler. This reduces memory overhead compared to attaching listeners to individual DOM nodes. The React documentation covers the full range of supported events, from mouse and keyboard events to pointer and touch events for mobile applications.

Conditional Rendering Techniques

React provides several ways to conditionally render content. The ternary operator is the most common for binary conditions:

{isLoggedIn ? <UserMenu /> : <LoginButton />}

Logical AND (&&) renders the right operand only when the left operand is truthy:

{unreadCount > 0 && <Badge count={unreadCount} />}

For multiple conditions, an IIFE or a separate function keeps JSX clean, though extracting a component is preferred for anything beyond trivial logic. Switch statements inside the render function or object maps also work well for multi-branch conditions.

Lists and Keys

Rendering lists using Array.map is fundamental to React. Each list item requires a unique key prop that helps React identify which items change, are added, or are removed:

{todos.map(todo => <TodoItem key={todo.id} todo={todo} />)}

Keys should be stable, unique, and predictable. Using array indices as keys is an anti-pattern that the React documentation warns against, especially when the list can be reordered or items can be inserted or removed. Index keys cause issues with incorrect state mapping, broken focus management, and inefficient re-rendering. The React Reconciliation documentation explains that keys enable O(n) diffing instead of O(n³) without them.

Lifting State Up

When multiple components need to reflect the same changing data, the state should be lifted to their closest common ancestor. This pattern, detailed in the React documentation’s “Lifting State Up” page, centralizes the truth and passes data down via props. Callbacks passed as props allow child components to communicate changes upward.

function TemperatureCalculator() {
  const [temperature, setTemperature] = useState('');
  return (
    <>
      <TemperatureInput scale="c" value={temperature} onChange={setTemperature} />
      <TemperatureInput scale="f" value={temperature} onChange={setTemperature} />
      <BoilingVerdict celsius={parseFloat(temperature)} />
    </>
  );
---

Practical Performance Considerations

React’s official documentation recommends using the React DevTools Profiler to identify performance bottlenecks. Common optimization strategies include:

  • Using React.memo to prevent unnecessary re-renders of pure components
  • Memoizing expensive computations with useMemo
  • Virtualizing long lists with libraries like react-window
  • Code splitting with React.lazy and Suspense
  • Avoiding inline object/function props that break referential equality

The React team’s blog post “Optimizing Performance” advises profiling before optimizing and warns that premature memoization can be worse than no optimization because it adds overhead without measurable benefit.

FAQ

Is React a framework or a library?

React is a library for building user interfaces. It handles the view layer and relies on the ecosystem for routing, state management, and other concerns. Frameworks like Next.js and Remix build on top of React to provide full application structure.

Do I need JSX to use React?

No. JSX is optional but recommended because it provides a concise and familiar syntax. You can use React.createElement directly, though most developers find JSX more readable.

What is the difference between React and ReactDOM?

React contains the core library (components, elements, hooks). ReactDOM is the renderer for web applications. React Native uses a different renderer for mobile platforms.

Should I learn class components or hooks?

Learn hooks. The React documentation recommends hooks for all new code, and class components are considered legacy. Understanding class components is useful for maintaining older codebases, but all modern React development uses function components with hooks.

How does React compare to Vue or Angular?

React gives you more freedom to choose your tools, while Angular provides an opinionated framework out of the box. Vue sits between them. React’s ecosystem is the largest, and its hiring market is the most active.

Conclusion

React’s component model, virtual DOM, and hooks API provide a powerful foundation for building modern user interfaces. The ecosystem around React — including Next.js, React Router, and state management libraries — makes it suitable for projects ranging from simple landing pages to complex enterprise applications. The official React documentation at react.dev remains the best starting point for learning, complemented by Dan Abramov’s blog and the React RFCs repository for understanding design decisions.

For a deeper dive into specific areas, explore React Components for composition patterns, React Hooks Guide for advanced hook usage, and React Server Components for the future of React architecture.

For a comprehensive overview, read our article on Next Js Guide.

For a comprehensive overview, read our article on React Authentication.

Section: React 1711 words 9 min read Intermediate 756 articles in section Report inaccuracy Back to top