Register to get access to free programming courses with interactive exercises

Application state JS: Frontend architecture

Manipulating the DOM is only a simple task in the most primitive situations. As soon as you need to implement a full-fledged (albeit small) application, coding it becomes infinitely more difficult. A dozen handlers is enough to get lost. The complexity of your code grows exponentially with each new event, and there are hundreds of events in real-world applications. Why does this happen?

Although it's not just the frontend part that gets affected by the problem, that's where it reaches its apogee. If you don't pay due attention, the DOM and event-driven architecture create waste no time in making your code confusing. It's clear that the architecture shows up here somewhere, but exactly where and how is another question.

Let's look at proper architecture from the perspective of backend development. As you already know or may have guessed, in terms of backend development, applications consist of at least two parts: a database and the code itself. Forms sent to the server change the application state (i.e., its data), which is stored in the database, then a response in the form of an HTML page is generated based on this state.

From the browser to the database via an application

In a typical web project, the application does essentially two things: it either updates the data in the database or it extracts that data and generates HTML code based on it. The need for a database is fairly obvious and understandable to everyone, but this isn't the case from the perspective of frontend development. The DOM allows you to store the state internally and, in fact, encourages you to do so. Throughout the course, we'll encounter this situation multiple times when we need to perform actions, and those actions depend on what's currently on the screen. To work with this data, you have to use the DOM.

The main problem with this approach is that there is no single source of truth. One piece of data on one page can be used many times, sometimes in different ways. Imagine a situation where you need to display the number of articles shown on a page. In order to count them, you have to write the following code:

// Each article is designated by the .article class
const articles = document.querySelectorAll('.article');
articles.length; // number of articles

And what if some of the articles are displayed in one block and the rest are displayed in a different one? That'll mean that you'll have to access both of these blocks to collect all the articles. The more we add, the more difficult it gets to add to, update, and use the data. If we look at the code, it's not easy for us to figure out where the data is coming from. In addition, the data are strongly tied to a specific layout structure.

Application state separation

The first step in building a proper architecture is to isolate the data that the application manipulates from the DOM. They need to be separated into a separate variable at the application level (not at the global level! Each instance the application is run must be independent of the others). This will allow you to separate working with the data from displaying it.

If you organize your code in this way, this is what you can expect:

  • An event occurs
  • The event handler changes the state
  • The DOM is updated based on new data

Below is an example of how this idea can be implemented using a simple counter. The state in this case is a single number. The plus button increases it by one, the minus button decreases it by one.

See the Pen js_dom_state_simple by Hexlet (@hexlet) on CodePen.

There are no calls to the DOM to retrieve the current value, it's stored in a variable and is available to all handlers. This sort of organization simplifies not only the storage and handling of data, but also debugging. At any time, you can look inside the state and compare it with what's displayed on the screen. The page itself becomes a reflection of the application state on the screen.


Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Profession
beginner
Development of front-end components for web applications
start anytime 10 months

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.