React vs Angular Renaissance: A Comprehensive Comparison
This website is powered by ItGalaxy.io
React and Angular Renaissance represent two distinct approaches to building modern web applications. While React emphasizes a JavaScript-first approach with hooks and JSX, Angular Renaissance brings a fresh take on the Angular framework with signals and improved template syntax. Let’s explore their differences across various aspects of web development.
Table of Contents
State Management
Declare State
React
import { useState } from "react";
export default function Name() {
const [name] = useState("John");
return <h1>Hello {name}</h1>;
}
Update State
React
import { useEffect, useState } from "react";
export default function Name() {
const [name, setName] = useState("John");
useEffect(() => {
setName("Jane");
}, []);
return <h1>Hello {name}</h1>;
}
Computed State
React
import { useState } from "react";
export default function DoubleCount() {
const [count] = useState(10);
const doubleCount = count * 2;
return <div>{doubleCount}</div>;
}
Templating
Minimal Template
Styling
React
import "./style.css";
export default function CssStyle() {
return (
<>
<h1 className="title">I am red</h1>
<button style={{ fontSize: "10rem" }}>I am a button</button>
</>
);
}
Loop
React
export default function Colors() {
const colors = ["red", "green", "blue"];
return (
<ul>
{colors.map((color) => (
<li key={color}>{color}</li>
))}
</ul>
);
}
Event Click
React
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
function incrementCount() {
setCount((count) => count + 1);
}
return (
<>
<p>Counter: {count}</p>
<button onClick={incrementCount}>+1</button>
</>
);
}
Angular Renaissance
import { Component, signal } from "@angular/core";
@Component({
selector: "app-counter",
template: `
<p>Counter: {{ count() }}</p>
<button (click)="incrementCount()">+1</button>
`,
})
export class CounterComponent {
count = signal(0);
incrementCount() {
this.count.update((count) => count + 1);
}
}
DOM Reference
React
import { useEffect, useRef } from "react";
export default function InputFocused() {
const inputElement = useRef(null);
useEffect(() => inputElement.current.focus(), []);
return <input type="text" ref={inputElement} />;
}
Angular Renaissance
import {
afterNextRender,
Component,
ElementRef,
viewChild,
} from "@angular/core";
@Component({
selector: "app-input-focused",
template: `<input type="text" #inputRef />`,
})
export class InputFocusedComponent {
inputRef = viewChild.required<ElementRef<HTMLInputElement>>("inputRef");
constructor() {
afterNextRender({ write: () => this.inputRef().nativeElement.focus() });
}
}
Conditional Rendering
React
import { useState } from "react";
const TRAFFIC_LIGHTS = ["red", "orange", "green"];
export default function TrafficLight() {
const [lightIndex, setLightIndex] = useState(0);
const light = TRAFFIC_LIGHTS[lightIndex];
function nextLight() {
setLightIndex((lightIndex + 1) % TRAFFIC_LIGHTS.length);
}
return (
<>
<button onClick={nextLight}>Next light</button>
<p>Light is: {light}</p>
<p>
You must
{light === "red" && <span>STOP</span>}
{light === "orange" && <span>SLOW DOWN</span>}
{light === "green" && <span>GO</span>}
</p>
</>
);
}
Angular Renaissance
import { Component, computed, signal } from "@angular/core";
const TRAFFIC_LIGHTS = ["red", "orange", "green"];
@Component({
selector: "app-traffic-light",
template: `
<button (click)="nextLight()">Next light</button>
<p>Light is: {{ light() }}</p>
<p>
You must @switch (light()) { @case ("red") {
<span>STOP</span>
} @case ("orange") {
<span>SLOW DOWN</span>
} @case ("green") {
<span>GO</span>
} }
</p>
`,
})
export class TrafficLightComponent {
lightIndex = signal(0);
light = computed(() => TRAFFIC_LIGHTS[this.lightIndex()]);
nextLight() {
this.lightIndex.update((index) => (index + 1) % TRAFFIC_LIGHTS.length);
}
}
Lifecycle
On Mount
React
import { useState, useEffect } from "react";
export default function PageTitle() {
const [pageTitle, setPageTitle] = useState("");
useEffect(() => {
setPageTitle(document.title);
}, []);
return <p>Page title: {pageTitle}</p>;
}
Angular Renaissance
import { Component, OnInit, signal } from "@angular/core";
@Component({
selector: "app-page-title",
template: `<p>Page title: {{ pageTitle() }}</p>`,
})
export class PageTitleComponent implements OnInit {
pageTitle = signal("");
ngOnInit() {
this.pageTitle.set(document.title);
}
}
On Unmount
React
import { useState, useEffect } from "react";
export default function Time() {
const [time, setTime] = useState(new Date().toLocaleTimeString());
useEffect(() => {
const timer = setInterval(() => {
setTime(new Date().toLocaleTimeString());
}, 1000);
return () => clearInterval(timer);
}, []);
return <p>Current time: {time}</p>;
}
Angular Renaissance
import { Component, OnDestroy, signal } from "@angular/core";
@Component({
selector: "app-time",
template: `<p>Current time: {{ time() }}</p>`,
})
export class TimeComponent implements OnDestroy {
time = signal(new Date().toLocaleTimeString());
timer = setInterval(
() => this.time.set(new Date().toLocaleTimeString()),
1000
);
ngOnDestroy() {
clearInterval(this.timer);
}
}
Component Composition
Props
React
import UserProfile from "./UserProfile.jsx";
export default function App() {
return (
<UserProfile
name="John"
age={20}
favouriteColors={["green", "blue", "red"]}
isAvailable
/>
);
}
Angular Renaissance
import { Component } from "@angular/core";
import { UserprofileComponent } from "./userprofile.component";
@Component({
selector: "app-root",
imports: [UserprofileComponent],
template: `
<app-userprofile
name="John"
[age]="20"
[favouriteColors]="['green', 'blue', 'red']"
[isAvailable]="true"
/>
`,
})
export class AppComponent {}
Emit to Parent
React
import { useState } from "react";
import AnswerButton from "./AnswerButton.jsx";
export default function App() {
const [isHappy, setIsHappy] = useState(true);
function onAnswerNo() {
setIsHappy(false);
}
function onAnswerYes() {
setIsHappy(true);
}
return (
<>
<p>Are you happy?</p>
<AnswerButton onYes={onAnswerYes} onNo={onAnswerNo} />
<p style={{ fontSize: 50 }}>{isHappy ? "😀" : "😥"}</p>
</>
);
}
Angular Renaissance
import { Component, signal } from "@angular/core";
import { AnswerButtonComponent } from "./answer-button.component";
@Component({
selector: "app-root",
imports: [AnswerButtonComponent],
template: `
<p>Are you happy?</p>
<app-answer-button (yes)="onAnswerYes()" (no)="onAnswerNo()" />
<p style="font-size: 50px">{{ isHappy() ? "😀" : "😥" }}</p>
`,
})
export class AppComponent {
isHappy = signal(true);
onAnswerYes() {
this.isHappy.set(true);
}
onAnswerNo() {
this.isHappy.set(false);
}
}
Slot
React
import FunnyButton from "./FunnyButton.jsx";
export default function App() {
return <FunnyButton>Click me!</FunnyButton>;
}
Slot Fallback
React
import FunnyButton from "./FunnyButton.jsx";
export default function App() {
return (
<>
<FunnyButton />
<FunnyButton>I got content!</FunnyButton>
</>
);
}
Angular Renaissance
import { Component } from "@angular/core";
import { FunnyButtonComponent } from "./funny-button.component";
@Component({
selector: "app-root",
imports: [FunnyButtonComponent],
template: `
<app-funny-button />
<app-funny-button>I got content!</app-funny-button>
`,
})
export class AppComponent {}
Context
React
import { useState } from "react";
import UserProfile from "./UserProfile";
import { UserContext } from "./UserContext";
export default function App() {
const [user, setUser] = useState({
id: 1,
username: "unicorn42",
email: "unicorn42@example.com",
});
function updateUsername(newUsername) {
setUser((userData) => ({ ...userData, username: newUsername }));
}
return (
<>
<h1>Welcome back, {user.username}</h1>
<UserContext.Provider value={{ ...user, updateUsername }}>
<UserProfile />
</UserContext.Provider>
</>
);
}
Angular Renaissance
import { Component, inject } from "@angular/core";
import { UserService } from "./user.service";
import { UserProfileComponent } from "./user-profile.component";
@Component({
imports: [UserProfileComponent],
providers: [UserService],
selector: "app-root",
template: `
<h1>Welcome back, {{ userService.user().username }}</h1>
<app-user-profile />
`,
})
export class AppComponent {
protected userService = inject(UserService);
}
Form Handling
Input Text
React
import { useState } from "react";
export default function InputHello() {
const [text, setText] = useState("Hello world");
function handleChange(event) {
setText(event.target.value);
}
return (
<>
<p>{text}</p>
<input value={text} onChange={handleChange} />
</>
);
}
Angular Renaissance
import { Component, signal } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
imports: [FormsModule],
selector: "app-input-hello",
template: `
<p>{{ text() }}</p>
<input [(ngModel)]="text" />
`,
})
export class InputHelloComponent {
text = signal("");
}
Checkbox
React
import { useState } from "react";
export default function IsAvailable() {
const [isAvailable, setIsAvailable] = useState(false);
function handleChange() {
setIsAvailable(!isAvailable);
}
return (
<>
<input
id="is-available"
type="checkbox"
checked={isAvailable}
onChange={handleChange}
/>
<label htmlFor="is-available">Is available</label>
</>
);
}
Angular Renaissance
import { Component, signal } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
imports: [FormsModule],
selector: "app-is-available",
template: `
<input id="is-available" type="checkbox" [(ngModel)]="isAvailable" />
<label for="is-available">Is available</label>
`,
})
export class IsAvailableComponent {
isAvailable = signal(false);
}
Radio
React
import { useState } from "react";
export default function PickPill() {
const [picked, setPicked] = useState("red");
function handleChange(event) {
setPicked(event.target.value);
}
return (
<>
<div>Picked: {picked}</div>
<input
id="blue-pill"
checked={picked === "blue"}
type="radio"
value="blue"
onChange={handleChange}
/>
<label htmlFor="blue-pill">Blue pill</label>
<input
id="red-pill"
checked={picked === "red"}
type="radio"
value="red"
onChange={handleChange}
/>
<label htmlFor="red-pill">Red pill</label>
</>
);
}
Angular Renaissance
import { Component, signal } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
imports: [FormsModule],
selector: "app-pick-pill",
template: `
<div>Picked: {{ picked() }}</div>
<input id="blue-pill" type="radio" value="blue" [(ngModel)]="picked" />
<label for="blue-pill">Blue pill</label>
<input id="red-pill" type="radio" value="red" [(ngModel)]="picked" />
<label for="red-pill">Red pill</label>
`,
})
export class PickPillComponent {
picked = signal("red");
}
Select
React
import { useState } from "react";
const colors = [
{ id: 1, text: "red" },
{ id: 2, text: "blue" },
{ id: 3, text: "green" },
{ id: 4, text: "gray", isDisabled: true },
];
export default function ColorSelect() {
const [selectedColorId, setSelectedColorId] = useState(2);
function handleChange(event) {
setSelectedColorId(event.target.value);
}
return (
<select value={selectedColorId} onChange={handleChange}>
{colors.map((color) => (
<option key={color.id} value={color.id} disabled={color.isDisabled}>
{color.text}
</option>
))}
</select>
);
}
Angular Renaissance
import { Component, signal } from "@angular/core";
import { FormsModule } from "@angular/forms";
@Component({
imports: [FormsModule],
selector: "app-color-select",
template: `
<select [(ngModel)]="selectedColorId">
@for (let color of colors; track: color) {
<option [value]="color.id" [disabled]="color.isDisabled">
{{ color.text }}
</option>
}
</select>
`,
})
export class ColorSelectComponent {
selectedColorId = signal(2);
colors = [
{ id: 1, text: "red" },
{ id: 2, text: "blue" },
{ id: 3, text: "green" },
{ id: 4, text: "gray", isDisabled: true },
];
}
Web App Features
Render App
React
<!DOCTYPE html>
<html>
<body>
<div id="app"></div>
<script type="module" src="./main.jsx"></script>
</body>
</html>
Fetch Data
React
import useFetchUsers from "./useFetchUsers";
export default function App() {
const { isLoading, error, data: users } = useFetchUsers();
return (
<>
{isLoading ? (
<p>Fetching users...</p>
) : error ? (
<p>An error occurred while fetching users</p>
) : (
users && (
<ul>
{users.map((user) => (
<li key={user.login.uuid}>
<img src={user.picture.thumbnail} alt="user" />
<p>
{user.name.first} {user.name.last}
</p>
</li>
))}
</ul>
)
)}
</>
);
}
Angular Renaissance
import { HttpClient } from "@angular/common/http";
import { inject, Injectable, signal } from "@angular/core";
export interface UsersState {
users: User[];
error: string | null;
loading: boolean;
}
export const initialState: UsersState = {
users: [],
error: null,
loading: false,
};
@Injectable({ providedIn: "root" })
export class UserService {
private http = inject(HttpClient);
#state = signal<UsersState>(initialState);
state = this.#state.asReadonly();
loadUsers() {
this.#state.update((state) => ({ ...state, loading: true }));
this.http
.get<UserResponse>("https://randomuser.me/api/?results=3")
.subscribe({
next: ({ results }) =>
this.#state.update((state) => ({ ...state, users: results })),
error: (error) => this.#state.update((state) => ({ ...state, error })),
});
}
}
Key Differences
-
State Management
- React uses hooks (
useState
,useEffect
) for state management - Angular Renaissance uses signals for fine-grained reactivity
- React uses hooks (
-
Templating
- React uses JSX with JavaScript expressions
- Angular uses template syntax with control flow operators (@if, @for, etc.)
-
Component Composition
- React passes children through props.children
- Angular uses content projection with ng-content
-
Form Handling
- React requires manual event handlers and state updates
- Angular provides NgModel for two-way binding
-
Dependency Injection
- React uses Context API for dependency injection
- Angular has a built-in dependency injection system
When to Choose React
- Large ecosystem and community
- JavaScript-first development
- Flexible architecture
- Minimal framework overhead
- Strong TypeScript support
- Need for custom renderers
When to Choose Angular Renaissance
- Enterprise-level applications
- Built-in dependency injection
- Strong TypeScript integration
- Comprehensive tooling
- Opinionated architecture
- Signal-based reactivity
Decouvrez plus d’Offres de la plateform ItGalaxy.io :
Découvrez notre gamme complète de services et formations pour accélérer votre carrière.
1. Nous contactez
- Description: Besoin de Formation et des Solutions cloud complètes pour vos applications
- Links:
2. Infra as a Service
- Description: Infrastructure cloud évolutive et sécurisée
- Links:
3. Projets Développeurs
- Description: Découvrez des opportunités passionnantes pour les développeurs
- Links:
4. Développeurs
- Description: Rejoignez notre communauté de développeurs
- Links:
5. Formations Complètes
- Description: Accédez à des formations professionnelles de haute qualité
- Links:
6. Marketplace
- Description: Découvrez notre place de marché de services
- Links:
7. Blogs
- Description: Découvrez nos blogs
- Links:
- comment creer une application mobile ?
- Comment monitorer un site web ?
- Command Checkout in git ?
- Comment git checkout to commit ?
- supprimer une branche git
- dockercoin
- kubernetes c est quoi
- architecture kubernetes
- Installer Gitlab Runner ?
- .gitlab-ci.yml exemples
- CI/CD
- svelte 5 vs solid
- svelte vs lit
- solidjs vs qwik
- alpine vs vue
- Plateform Freelance 2025
- Creation d’un site Web gratuitement
This website is powered by ItGalaxy.io
Decouvrez plus d’Offres de la plateform ItGalaxy.io :
Découvrez notre gamme complète de services et formations pour accélérer votre carrière.
1. Nous contactez
- Description: Besoin de Formation et des Solutions cloud complètes pour vos applications
- Links:
2. Infra as a Service
- Description: Infrastructure cloud évolutive et sécurisée
- Links:
3. Projets Développeurs
- Description: Découvrez des opportunités passionnantes pour les développeurs
- Links:
4. Développeurs
- Description: Rejoignez notre communauté de développeurs
- Links:
5. Formations Complètes
- Description: Accédez à des formations professionnelles de haute qualité
- Links:
6. Marketplace
- Description: Découvrez notre place de marché de services
- Links:
7. Blogs
- Description: Découvrez nos blogs
- Links:
- comment creer une application mobile ?
- Comment monitorer un site web ?
- Command Checkout in git ?
- Comment git checkout to commit ?
- supprimer une branche git
- dockercoin
- kubernetes c est quoi
- architecture kubernetes
- Installer Gitlab Runner ?
- .gitlab-ci.yml exemples
- CI/CD
- svelte 5 vs solid
- svelte vs lit
- solidjs vs qwik
- alpine vs vue
- Plateform Freelance 2025
- Creation d’un site Web gratuitement
This website is powered by ItGalaxy.io