DEV Community

Alireza Razinejad
Alireza Razinejad

Posted on

Demystifying MVC Architecture in Modern Web Frameworks: React and Angular

As web development evolves, so do the architectural patterns we use. While MVC (Model-View-Controller) is a staple in software design, adapting it to frameworks like React and Angular can optimize our projects for better scalability and maintainability. Here’s a quick guide on how you can implement MVC-like structures in both frameworks:

React and MVC:

React is predominantly view-oriented, focusing on UI components. However, incorporating Redux allows us to neatly separate concerns:

Model: Redux Store manages application state, acting as a single source of truth.

// Redux store (model.js)
import { createStore } from 'redux';

const initialState = {
    counter: 0
};

function reducer(state = initialState, action) {
    switch (action.type) {
        case 'INCREMENT':
            return { ...state, counter: state.counter + 1 };
        case 'DECREMENT':
            return { ...state, counter: state.counter - 1 };
        default:
            return state;
    }
}

const store = createStore(reducer);
export default store;
Enter fullscreen mode Exit fullscreen mode

View and Controller: React components render UI and handle user interactions, dispatching actions to update the model.

// Counter.js (React component)
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

const Counter = () => {
    const counter = useSelector(state => state.counter);
    const dispatch = useDispatch();

    return (
        <div>
            <h1>Counter: {counter}</h1>
            <button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
            <button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
        </div>
    );
}

export default Counter;
Enter fullscreen mode Exit fullscreen mode

Angular Embraces MVC Naturally:

Angular’s robust structure supports MVC more directly with its component and service architecture:

Model: Services in Angular manage data logic and state, similar to traditional MVC models.

// counter.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class CounterService {
  private counter = new BehaviorSubject<number>(0);

  getCounter() {
    return this.counter.asObservable();
  }

  incrementCounter() {
    this.counter.next(this.counter.value + 1);
  }

  decrementCounter() {
    this.counter.next(this.counter.value - 1);
  }
}
Enter fullscreen mode Exit fullscreen mode

View: Templates render the UI, binding directly to the component class.

<!-- counter.component.html -->
<div>
  <h1>Counter: {{ counter | async }}</h1>
  <button (click)="increment()">Increment</button>
  <button (click)="decrement()">Decrement</button>
</div>
Enter fullscreen mode Exit fullscreen mode

Controller: Angular components handle data and user interactions, communicating with services.

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

@Component({
  selector: 'app-counter',
  templateUrl: './counter.component.html'
})
export class CounterComponent {
  counter = this.counterService.getCounter();

  constructor(private counterService: CounterService) {}

  increment() {
    this.counterService.incrementCounter();
  }

  decrement() {
    this.counterService.decrementCounter();
  }
}
Enter fullscreen mode Exit fullscreen mode

Both React and Angular offer unique takes on MVC, adapting its core principles to the component-driven development landscape. By understanding these patterns, developers can create more organized and manageable codebases.

👉 If you're looking to deepen your understanding or considering integrating MVC into your projects, let's connect and discuss how these patterns can be tailored to fit your needs!

Top comments (0)