Background Mobile

Understanding React.js for Frontend Development

frontend/
September 17, 2026
Understanding React.js for Frontend Development

React.js has been the dominant choice for frontend development since Facebook open-sourced it in 2013. If you're evaluating it seriously — deciding how deep to go, what architecture to adopt, or whether it's even the right fit — this is a practical breakdown of what it actually involves to build production-grade React applications.

What Makes React Different From Other Frontend Frameworks?

React is not a full framework. It is a UI library. That distinction matters because it means you make more decisions yourself: routing, state management, data fetching, form handling. Angular ships with opinions on all of these. React does not.

The core idea is the virtual DOM. React maintains a lightweight in-memory representation of the actual DOM. When state changes, it diffs the virtual tree against the previous one and applies only the necessary updates to the real DOM. This avoids expensive full-page re-renders and is why React feels fast under normal conditions.

The component model is the other foundational concept. Everything is a component — a JavaScript function that returns JSX (JavaScript XML). Components compose into trees. Data flows down through props; events bubble up through callbacks. This one-way data flow makes it straightforward to trace where a bug originates, which is not something you can say about two-way binding systems.

JSX Is Not HTML

JSX looks like HTML but compiles to React.createElement calls. Attributes like class become className, for becomes htmlFor, and event handlers are camelCased (onClick, not onclick). Tools like Babel and SWC handle this compilation at build time. Understanding that JSX is syntax sugar over function calls explains a lot of React's behaviour that trips up newcomers.

How Does State Management Actually Work in a React Application?

This is where most teams make consequential architectural decisions early, and where changing course later is painful.

React's built-in state primitives are useState and useReducer. For local component state, these are sufficient and correct. The mistake teams make is reaching for external state libraries before they actually need them.

Context API is the built-in solution for sharing state across a tree without prop drilling. It works well for low-frequency updates — themes, authentication state, user preferences. It is a poor choice for high-frequency updates because every consumer re-renders when the context value changes.

For genuinely complex global state, the main options are:

  • Redux Toolkit (RTK): Still the most widely adopted. RTK simplified Redux considerably — createSlice, createAsyncThunk, and RTK Query reduced boilerplate significantly compared to classic Redux. It's predictable and debuggable via Redux DevTools.
  • Zustand: Much lighter. A store is a single hook. Good for medium-complexity apps where Redux's structure feels like overhead.
  • Jotai / Recoil: Atomic state models. Fine-grained subscriptions mean components only re-render when the specific atom they depend on changes.
  • React Query (TanStack Query): Not a global state library, but it handles server state — caching, background refetching, stale-while-revalidate — better than most teams implement manually with Redux.

A common production pattern is to use React Query for server state and Zustand for the relatively small slice of genuine client-side global state. Most applications have less client state than engineers assume.

/// Not sure where to start?

Get the architecture before you commit

Tell us what you're building and we'll map the technical approach, stack, and rough timeline. No cost, no obligation, no sales call required.

What Does a Production-Ready React Architecture Look Like?

A project that starts with create-react-app and grows organically tends to accumulate technical debt fast. A few structural decisions made early pay off over time.

File and Folder Structure

There is no single correct structure, but co-location is generally better than separation by type. Keeping a component, its styles, its tests, and its hooks in one folder makes it easier to delete or move without archaeology.

A feature-based structure works well at scale:

src/
  features/
    auth/
      components/
      hooks/
      api/
      index.ts
    dashboard/
      ...
  shared/
    components/
    utils/

Rendering Strategies

Plain React renders client-side. That is fine for dashboards and internal tools, but it means the user gets a blank page until JavaScript executes and data loads. For public-facing pages, SEO, or performance on lower-end devices, you need a different approach.

Next.js is the de facto standard for server-side rendering (SSR) and static site generation (SSG) with React. Version 13 introduced the App Router and React Server Components (RSC), which run on the server and send rendered HTML with zero client-side JavaScript. This changes the mental model considerably — you have to think explicitly about which components need client interactivity and which do not.

Remix is a strong alternative, particularly for applications with complex data mutation flows. Its loader/action model makes form handling and error boundaries feel more coherent than Next.js's approach.

Approach Best For Trade-offs
Vite + React (CSR) Internal tools, dashboards No SSR; blank page on load
Next.js (App Router) Public sites, e-commerce, SEO-sensitive apps More complex mental model with RSC
Remix Data-heavy apps with mutations Smaller ecosystem, steeper learning curve
Next.js (Pages Router) Teams familiar with pre-v13 Next Being gradually deprecated

Performance Optimisation

React re-renders components when state or props change. Unnecessary re-renders compound into visible sluggishness on complex UIs. The tools to control this are React.memo (memoises a component), useMemo (memoises a computed value), and useCallback (memoises a function reference).

The rule of thumb: profile first, optimise second. React DevTools Profiler shows which components render and how long they take. Premature memoisation adds complexity without measurable benefit and can introduce bugs when dependency arrays are wrong.

Code splitting with React.lazy and Suspense defers loading of non-critical code. In a large application, splitting by route alone can reduce initial bundle size by 40–60%.

Testing React Applications Without Losing Your Mind

The standard testing stack is:

  • Vitest or Jest as the test runner
  • React Testing Library (RTL) for component tests
  • Playwright or Cypress for end-to-end tests

RTL's philosophy is to test behaviour, not implementation. Query by accessible role or label text, not by component internals. This means tests survive refactors better.

Unit testing individual utility functions is straightforward. The harder question is how much to invest in component tests versus end-to-end tests. Component tests are fast but test in isolation. End-to-end tests are slow but test the actual user flow. A reasonable split for a medium-sized product is heavy unit tests on business logic, moderate component tests on critical UI flows, and a small suite of E2E tests on the most important journeys (checkout, login, core CRUD operations).

Conclusion

React is a capable, well-supported library with a mature ecosystem. The core API has been stable since hooks landed in v16.8 in 2019. The decisions that actually define how well a React project goes are the ones around architecture — state management, rendering strategy, and testing discipline — not the library itself.

If you're starting a new project, pick a rendering strategy before you write a component. If you're inheriting one, run the React DevTools Profiler before you do anything else. That's the fastest way to understand what you're actually dealing with.


FAQ

Does React still make sense in 2025, or have newer frameworks overtaken it? React remains the most widely used frontend library, with around 40% of developers using it according to the 2023 Stack Overflow Developer Survey. Svelte and Solid.js offer better raw performance in benchmarks, but React's ecosystem, tooling, and hiring pool are significantly larger. For most teams, that matters more than benchmark scores.

What is the difference between React Server Components and server-side rendering? SSR renders a full page on the server per request and sends HTML. React Server Components (RSC) are components that run only on the server and never ship JavaScript to the client. They can coexist with client components in the same tree. RSC reduces bundle size; SSR reduces time-to-first-byte. They solve related but different problems.

When should I not use React? If you're building a mostly static marketing site with minimal interactivity, a lighter tool like Astro or even plain HTML with a small amount of JavaScript is more appropriate. React adds meaningful overhead — both in bundle size and in cognitive complexity — that isn't justified for simple content sites.

How do I handle authentication state in a React app? Store tokens in httpOnly cookies when possible, not localStorage. Use a Context provider wrapping your router to expose the current user. Libraries like NextAuth.js (for Next.js) or Supabase Auth handle the session management layer. Don't roll your own token validation logic on the client.

What's the right way to fetch data in React? With Next.js App Router, use async Server Components for data that doesn't need client interactivity. For client-side fetching, TanStack Query is the most complete solution — it handles caching, deduplication, background refetching, and loading/error states in a consistent API. Avoid raw useEffect + fetch patterns for anything beyond simple one-off requests.

Have a project in mind? Contact Sodio Technologies to discuss your requirements and explore the right technology solution for your business.

/// Work with us

Talk to the engineers who'd build it

You'll get a technical scope, timeline and cost estimate from the people doing the work, not an account manager. In-house team, no subcontracting, since 2016.

Contact Us