DEV Community

Shriram
Shriram

Posted on • Edited on

Code Comparison: React vs Angular

In this blog, I would like to compare and contrast two of the most popular ways to develop UI using JavaScript out there: React and Angular. I started web development using React three years ago and it was my go-to framework for building web apps. However, I had to learn and build apps using Angular for work. While there are a lot of articles out there for choosing a suitable one of these two for building your applications, I would like to compare them syntactically, which would be helpful for developers switching to Angular after learning React and vice versa. We will discuss the following key paradigms in this blog.

  • Writing markup
  • Dynamic markups
  • Sharing data between parent and child
  • Lifecycle management
  • Event handling

Writing markup

One of the key differences between React and Angular is the way HTML markup is written. In React, markup and logic are coupled in units called Components. React uses JSX, an extension to JavaScript, which can contain HTML markup and the associated rendering logic together.

export default function HelloWorld(){
    let name = "Arthur";

    return(
        <h1 className="heading">Welcome, {name}</h1>
    )
}
//Home.jsx
Enter fullscreen mode Exit fullscreen mode

In Angular, markup and logic are written in separate files and there is a clearly defined separation of concern. Angular uses Typescript instead of JavaScript, where Typescript is a superset of JavaScript with optional static typing.

export class HelloWorldComponent {
    name:string="Arthur";
    constructor() { }
}
//home.component.ts
Enter fullscreen mode Exit fullscreen mode
<h1 class="heading">Welcome, {{name}}</h1>
<!--home.component.html-->
Enter fullscreen mode Exit fullscreen mode

Dynamic markups

The ability to render markups conditionally to show desired elements in the HTML layout and hide the remaining based on criteria defined in JavaScript code is necessary to create modern web applications. Markups must also be created dynamically in a loop to keep the html code dry. There may be many different ways to generate a desired markup in any given framework, and I have explored only one such way in the example below.

In React, for conditional rendering, the desired markup may be stored as jsx in a variable using the ternary operator. A function can also be written to return the desired jsx using the commonly used If…else condition. For looping over an array and generating markup, map function is commonly used.

export default function Home(){
    let name = "Arthur";
    let isSignedIn=true;
    let products=['Macbook Air','Ipad Air','Iphone SE'];
    const homeJSX=isSignedIn?(
        <div>
            <h1>Welcome, {name}</h1>
            <h2>Products</h2>
            <ul>
                {products.map((product)=><li key={product}>{product}</li>)}
            </ul>
        </div>
    ):(
        <h1>You are not signed in</h1>
    );

    return(
        <div>
            {homeJSX}
        </div>
    );
}
//Home.jsx
Enter fullscreen mode Exit fullscreen mode

Angular takes a different approach when it comes to dynamic rendering, and it has built-in structural directives such as NgIf and NgFor. In Angular, the markup generated by React can be generated as follows.

export class HomeComponent {
    name:string="Arthur";
    isSignedIn:boolean=true;
    products:Array<string>=['Macbook Air','Ipad Air','Iphone SE']
  constructor() { }
}
//home.component.ts
Enter fullscreen mode Exit fullscreen mode
<div>
    <div *ngIf="isSignedIn; else elseBlock">
        <h1>Welcome to the application</h1>
        <h2>Products</h2>
        <ul>
            <li *ngFor="let product of products">{{product}}</li>
        </ul>
    </div>
    <ng-template #elseBlock><h1>You are not signed in</h1></ng-template>
</div>
<!--home.component.html-->
Enter fullscreen mode Exit fullscreen mode

Sharing data between parent and child

In React and Angular, parents and children can share data with each other using props. While the data flow from parent to child is straightforward by passing props to the child component, data flow from child to parent is achieved by passing a parent function that stores the data as a prop to the child. One such implementation in React will follow.

export default function Home(){
    const [count, setCount]=useState(0);

    return(
        <Child count={count} setCount={setCount}/>
    );
}
//Home.jsx
Enter fullscreen mode Exit fullscreen mode
export default function Child({count,setCount}){

    return(
        <div>
            <input type="number" value={count} onChange={(e)=>setCount(e.target.value)} />
        </div>
    );
}
//Child.jsx
Enter fullscreen mode Exit fullscreen mode

Angular provides input and output decorators that enable a child component to interact with its parent. The above data flow in React can be implemented in Angular as follows.

export class HomeComponent {
    count!:number;
  constructor() { }

    setCount(newCount:number){
        this.count=newCount;
    }
}
//home.component.ts
Enter fullscreen mode Exit fullscreen mode
<div>
    <app-child [count]="count" (setCount)="setCount($event)"></app-child>
</div>
<!--home.component.html-->
Enter fullscreen mode Exit fullscreen mode
export class ChildComponent {
    @Input() count!:number;
    @Output() setCount= new EventEmitter<number>();
  constructor() { }

}
//child.component.ts
Enter fullscreen mode Exit fullscreen mode
<div>
    <input type="number" [value]="count" (change)="this.setCount.emit($event.target.value)" />
</div>
<!--child.component.html-->
Enter fullscreen mode Exit fullscreen mode

Lifecycle management

Lifecycle management gives developers control over code to be executed during the creation, updation and deletion of a component. React uses several hooks to handle the lifecycle with the useEffect hook being the preferred way to handle common scenarios.

export default function Home({count}){

    useEffect(()=>{
        console.log("Component created");

        return () => {
      console.log('Component deleted');
    };
    },[]);

    useEffect(()=>{
        console.log("Count changed");
    },[count]);

}
//Home.jsx
Enter fullscreen mode Exit fullscreen mode

Angular provides different hooks for lifecycle management. ngOnInit, ngOnChanges and ngOnDestroy are the most commonly used hooks. The above lifecycle behaviour in React can be implemented in Angular as follows.

export class HomeComponent {
    @Input() count!:number;

  constructor() { }

    ngOnInit(){
        console.log("Component created");
    }

    ngOnChanges(change:SimpleChanges){
        if(change["count"]){
            console.log("Count changed");
        }
    }

    ngOnDestroy(){
        console.log("Component deleted");
    }

}
//home.component.ts
Enter fullscreen mode Exit fullscreen mode

Event handling

User interaction is critical for any web application and the associated events such as click, keypress has to be handled by the application. React has its synthetic events which are wrapper functions over native events implemented by browsers to provide cross-browser uniformity. One such event-handling scenario is discussed here.

export default function Home(){
    handleKeyDown=(event)=>{
        console.log("You pressed: ",event.key);
    }

    return(
        <div>
            <input onKeyDown={handleKeyDown}/>
        </div>
    )
}
//Home.jsx
Enter fullscreen mode Exit fullscreen mode

In Angular, we have to create event bindings as follows to listen and respond to events.

export class HomeComponent {
  constructor() { }

    handleKeyDown(event){
        console.log('You pressed: ',event.key);
    }
}
//home.component.ts
Enter fullscreen mode Exit fullscreen mode
<div>
    <input (keydown)='handleKeyDown($event)'/>
</div>
<!--home.component.html-->
Enter fullscreen mode Exit fullscreen mode

We did a code comparison of the most common use cases of React and Angular. Both are amazing library/framework for creating a frontend application. There are other differences between them part from the ones mentioned here, which we can discuss in a different blog. Thank you for reading. Cheers!

Top comments (18)

Collapse
 
amir2mi profile image
Amir M. Mohamadi

Clearly React has cleaner syntax, my second choice after React would be Vue for sure.

Collapse
 
dylanwatsonsoftware profile image
Dylan Watson

I don't think it's that clear cut though. React is nice but Angular's ability to separate html from typescript code is actually quite good for debugging.

It means Angular's html will be much closer to reality than React in practice.

Collapse
 
brense profile image
Rense Bakker • Edited

Really? Html has an ng-if element?

Thread Thread
 
dylanwatsonsoftware profile image
Dylan Watson

Haha Obviously not BUT it will render just fine with it!

Thread Thread
 
mellunar profile image
mellunar

I'm confused about how {submitError && <p className='product-submit-error'>{submitError}</p>} is closer to a html element than <p class='product-submit-error' *ngIf="submitError">{{submitError}}</p>

Collapse
 
nermin_karapandzic profile image
Nermin Karapandzic

clearly you are biased, or you don't know what clean means.

Collapse
 
amir2mi profile image
Amir M. Mohamadi

I think it's more about personal preference, as I said if I wanted to use Angular ng-fied attributes, I would go for Vue.js.

Collapse
 
amar9312 profile image
Amardeep
export class HomeComponent {
    @Input() count!:number;
    @Output() setCount= new EventEmitter<number>();
  constructor() { }

}
Enter fullscreen mode Exit fullscreen mode

I think the class name should be ChildComponent if I am not wrong

Collapse
 
shriram27 profile image
Shriram

You're right., I have corrected it. Thank you for pointing out the error :)

Collapse
 
innoflash profile image
Innocent Mazando

We can all be religious about our preferences but honestly Angular is top notch with it's SRP approach to problems, no wonder it's the best for wiring enterprise apps. Think React is too free style to write something that's maintainable over time

Collapse
 
danielepecora profile image
Daniele Pecora

Can't really sympathize with react JSX mixing view with controller code. Angular has an approach that follows better the separation of concerns paradigma.

Collapse
 
xanderselorm profile image
Alexander Selorm Kubi

You can always use hooks in react to separate your business logics. 😊

Collapse
 
brownieboy profile image
Michael Brown

Putting stuff in separate files !== separation of concerns. Angular controllers and templates are joined at the him.

Collapse
 
danielepecora profile image
Daniele Pecora

"...The separation of concerns is achieved using modularization, encapsulation and arrangement in software layers."

An Angular distinguishes between this aspects of a project:
-Modules
-Components
-Services
-Templates
-Metadata
-Data binding
-Directives
-Dependency Injection

If this and separating the presentation layer into view and logic is not some kind of "encapsulating" then I don't know.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

In my mind, only Svelte exists. 😎

But if Svelte didn't exist, Vue would be my choice. React seems to be the grandpa now: Shaped the future, but the future has surpassed it.

Collapse
 
eternal21 profile image
Eternal21

React is great if you need to write some unmaintainable spaghetti code quickly. For anything enterprise related, that you'll actually need to support long-term Angular is the way to go.

Collapse
 
tryagain profile image
Mohamed M.

Angular natural separation of concern make it easier to read and pick-up as a newbie

Collapse
 
mellunar profile image
mellunar

Angular looks difficult, but I found it way better to learn than the React spaghetti. After Svelte, we shouldn't even talk about React anymore.