Hassan Agmir Hassan Agmir

React vs. Angular: Code examples

Hassan Agmir
React vs. Angular: Code examples

1. Introduction

In the modern web development landscape, building high-performance, maintainable, and scalable user interfaces is critical. React and Angular stand out as two of the dominant solutions for crafting rich single-page applications (SPAs). Despite sharing some similarities—both let developers create reusable UI components—they differ fundamentally in philosophy, architecture, and feature set.

This comprehensive guide dives deep into React and Angular, comparing their histories, core principles, performance characteristics, developer tooling, ecosystem support, and more. We’ll also showcase practical code examples illustrating how the two approaches diverge in common tasks.

By the end of this article, you’ll have a clear picture of which technology aligns best with your project requirements, team expertise, and long-term maintainability goals.

2. Historical Background

React

  • Release Date: March 2013
  • Creator: Facebook (now Meta)
  • Philosophy: Start small—a library for building UI components—and let the ecosystem grow around it.

React introduced the concept of a virtual DOM, enabling high-performance updates by diffing changes and applying them in batches. Its unidirectional data flow and JSX syntax (JavaScript + XML) revolutionized how developers thought about component construction.

Angular

  • Release Date: October 2010 (AngularJS), September 2016 (Angular 2+)
  • Creator: Google
  • Philosophy: Provide a full-featured, batteries-included framework to cover all aspects of front-end development out of the box.

AngularJS (v1.x) pioneered declarative two-way data binding, but performance issues in large applications led to the complete rewrite known as Angular (or Angular 2+), embracing TypeScript, improved dependency injection, and component-based architecture.

3. Philosophy & Architecture

3.1 React’s Component-Based Library Approach

React is best described as a UI library. It focuses solely on building user interfaces and leaves ancillary concerns—like state management, routing, and build tooling—to the broader ecosystem.

  • JSX: JavaScript syntax extension allowing HTML-like code in JS files.
  • Virtual DOM: Efficient diffing and patching.
  • Unidirectional Data Flow: Props flow from parent to child; state is local to each component unless external management is used.

This minimal core allows developers to assemble best-of-breed tools for routing (e.g., React Router), state management (e.g., Redux, MobX), and build systems (Webpack, Vite).

3.2 Angular’s Full-Fledged Framework Approach

Angular is a complete framework. It prescribes a structured approach to application architecture, providing solutions for:

  • CLI: Project scaffolding, building, testing.
  • Modules & Dependency Injection (DI): Organize code into cohesive units.
  • Ahead-of-Time (AOT) Compilation: Compile templates into highly optimized JavaScript before runtime.
  • Forms API: Template-driven and reactive forms.
  • HTTP Client: Built-in service for HTTP requests.
  • Router: Advanced routing with guards, lazy loading.

This all-in-one approach offers consistency and conventions at the cost of initial learning curve and bundle size.

4. Core Concepts

4.1 Components & Templates

React

  • Function or class components.
  • JSX for templating.
  • Hooks (useState, useEffect) for lifecycle and state.

Angular

  • Decorators (@Component) to define metadata.
  • External HTML templates or inline templates.
  • Lifecycle hooks (ngOnInit, ngOnChanges).

4.2 Modules & Routing

React

  • No built-in module system; relies on ES modules.
  • React Router for route definitions.

Angular

  • NgModules (@NgModule) group components, directives, pipes, and providers.
  • RouterModule for routing, with built-in guards and parameters.

4.3 State Management

React

  • Local state with useState.
  • Context API for global state.
  • Redux, MobX, Recoil for complex needs.

Angular

  • Services with DI for shared state.
  • NgRx (Redux-inspired) for large-scale state management.

5. Data Binding & Change Detection

React

  • One-way binding: Props down, events up.
  • Manual control over when to re-render via shouldComponentUpdate or React.memo.

Angular

  • Two-way binding: [(ngModel)] combines property binding and event binding.
  • Change detection strategies: Default vs. OnPush.

6. Performance Considerations

  • Bundle Size: Angular apps often start larger; React’s modularity can yield smaller initial payloads, but ecosystem choices matter.
  • Rendering: React’s virtual DOM diffing vs. Angular’s change detection tree.
  • Lazy Loading: Both support route-based lazy loading; Angular CLI automates it.

7. Tooling & Developer Experience


Feature React Angular
| CLI  | Create React App, Vite  | Angular CLI
| Language  | JavaScript, TypeScript (optional)  | TypeScript (mandatory)
| Testing  | Jest, React Testing Library  | Jasmine, Karma
| Linting & Formatting  | ESLint, Prettier  | TSLint (deprecated), ESLint with plugins
| IDE Support  | VSCode, WebStorm  | VSCode, WebStorm, built-in Angular Language Service

8. Ecosystem & Community

  • React: Vast ecosystem, many competing libraries, numerous learning resources.
  • Angular: Structured ecosystem, official modules, consistent updates from Google.

9. Real-World Code Examples

Below are parallel implementations of common tasks.

9.1 Building a Simple Counter

React Example

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
}

export default Counter;

Angular Example

// counter.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: `
    <div>
      <h1>Count: {{ count }}</h1>
      <button (click)="increment()">Increment</button>
      <button (click)="decrement()">Decrement</button>
    </div>
  `
})
export class CounterComponent {
  count = 0;

  increment() { this.count++; }
  decrement() { this.count--; }
}

9.2 Form Handling

React Example (Controlled Components)

import React, { useState } from 'react';

function NameForm() {
  const [name, setName] = useState('');

  const handleSubmit = e => {
    e.preventDefault();
    alert(`Submitting Name: ${name}`);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input
          type="text"
          value={name}
          onChange={e => setName(e.target.value)}
        />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default NameForm;

Angular Example (Reactive Forms)

// app.module.ts
import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [ReactiveFormsModule]
})
export class AppModule {}

// name-form.component.ts
import { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-name-form',
  template: `
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <label>
        Name:
        <input formControlName="name" />
      </label>
      <button type="submit">Submit</button>
    </form>
  `
})
export class NameFormComponent {
  form = new FormGroup({
    name: new FormControl('')
  });

  onSubmit() {
    alert(`Submitting Name: ${this.form.value.name}`);
  }
}

9.3 HTTP Requests & Data Fetching

React Example (Fetch API)

import React, { useEffect, useState } from 'react';

function DataFetcher() {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch('https://api.example.com/items')
      .then(res => res.json())
      .then(setData)
      .catch(console.error);
  }, []);

  if (!data) return <div>Loading...</div>;
  return (
    <ul>
      {data.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

export default DataFetcher;

Angular Example (HttpClient)

// app.module.ts
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [HttpClientModule]
})
export class AppModule {}

// data-fetcher.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-data-fetcher',
  template: `
    <ul *ngIf="data">
      <li *ngFor="let item of data">{{ item.name }}</li>
    </ul>
    <div *ngIf="!data">Loading...</div>
  `
})
export class DataFetcherComponent implements OnInit {
  data: any[] | null = null;

  constructor(private http: HttpClient) {}

  ngOnInit() {
    this.http.get<any[]>('https://api.example.com/items')
      .subscribe({ next: items => this.data = items, error: console.error });
  }
}

10. Pros & Cons

Aspect React Angular
| Learning Curve  | Low to moderate (JSX and ecosystem choices)  | Steeper (TypeScript, DI, RxJS, CLI)
| Flexibility  | High (choose your tools)  | Consistent (official libraries and patterns)
| Bundle Size  | Potentially smaller when optimized  | Larger initial footprint
| Performance  | Fast virtual DOM diffing  | Efficient with AOT and change detection
| Community Support  | Massive, diverse  | Strong, more opinionated
| Enterprise Usage  | Widely used  | Preferred in many large enterprises (Google, Microsoft partners)

11. When to Choose Which

  • Choose React if:
    • You need maximum flexibility in tooling and architecture.
    • You prefer a library with minimal conventions.
    • You want a smaller initial bundle and can customize optimizations.
  • Choose Angular if:
    • You want a complete, opinionated framework with all core features built-in.
    • You work in a large team or enterprise environment that benefits from strong conventions.
    • You prefer TypeScript by default and extensive CLI tooling.

12. Conclusion

React and Angular each bring unique strengths. React’s lightweight, library-centric approach empowers developers to assemble bespoke toolchains, while Angular’s battery-included framework accelerates development with built-in solutions for routing, forms, HTTP, and more.

Ultimately, the best choice depends on your project requirements, team expertise, and long-term maintenance considerations. Weigh the trade-offs—learning curve, performance, ecosystem—and select the tool that aligns best with your application’s needs.

Subscribe to my Newsletters

Stay updated with the latest programming tips, tricks, and IT insights! Join my community to receive exclusive content on coding best practices.

© Copyright 2025 by Hassan Agmir . Built with ❤ by Me