Published on

Building a React Application with MVVM Pattern

Building a React Application with MVVM Pattern

Building a React Application with MVVM Pattern

Building a React Application with Custom EventEmitter and MVVM Pattern

In this article, we'll dive into a powerful architectural pattern that combines modern JavaScript, React, and a custom implementation of an EventEmitter to manage state changes in a reactive and efficient manner. This approach leverages the Model-View-ViewModel (MVVM) pattern, traditionally used in frameworks like Angular and Vue, and adapts it to React applications. The MVVM pattern can enhance your project's structure by providing a clear separation of concerns, which simplifies management and improves scalability.

Setting Up the Environment

To begin, ensure Node.js is installed on your machine. We'll start a new React project using Create React App:

npx create-react-app react-mvvm-demo
cd react-mvvm-demo
npm start

Creating a Custom EventEmitter Class

Our first step is to create a custom EventEmitter class. This class will manage event subscriptions and notifications:

class EventEmitter {
  constructor() { = {};

  on(eventName, listener) {
    if (![eventName]) {[eventName] = [];

  off(eventName, listener) {
    if (![eventName]) {
    }[eventName] =[eventName].filter(
      (l) => l !== listener

  emit(eventName, data) {
    const event =[eventName];
    if (event) {
      event.forEach((listener) => {

Extending UserModel with EventEmitter

Next, we extend this EventEmitter to create a UserModel class. This model will manage user data and emit updates whenever the user list changes:

class UserModel extends EventEmitter {
  constructor() {
    this.users = [];

  addUser(user) {
    this.emit("update", this.users);

  getUsers() {
    return this.users;

Building the React Component

We then build a React component that listens to updates from our UserModel:

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

const userModel = new UserModel();

const UserComponent = () => {
  const [users, setUsers] = useState(userModel.getUsers());

  useEffect(() => {
    const handleUpdate = (newUsers) => {

    userModel.on("update", handleUpdate);

    return () =>"update", handleUpdate);
  }, []);

  const handleAddUser = () => {
    userModel.addUser({ name: "New User", id: });

  return (
      <button onClick={handleAddUser}>Add User</button>
        { => (
          <li key={}>{}</li>

export default UserComponent;

Integration into App.js

Finally, we integrate our UserComponent into the main App component to display it within our application:

import React from "react";
import UserComponent from "./UserComponent";

function App() {
  return (
    <div className="App">
      <h1>User Management</h1>
      <UserComponent />

export default App;


In this blog, we've successfully implemented an MVVM pattern in a React application using a custom EventEmitter class. This architecture not only provides a clean separation between the application's logical and presentation layers but also enhances the scalability and maintainability of the code. By creating a decoupled system where components communicate through events, developers can build more flexible and manageable applications.

Potential Use Cases

  1. Real-time Applications: Ideal for scenarios requiring real-time updates like chat apps or live sports scores.
  2. Complex UIs: Simplifies communication in complex interfaces, avoiding prop drilling and callback chains.
  3. Server-side Events: Can integrate seamlessly with server-side push technologies like WebSockets for reactive updates.

Using a custom EventEmitter with React opens up a realm of possibilities for crafting sophisticated web applications that are both robust and easy to maintain.