Register to get access to free programming courses with interactive exercises

Form State JS: Frontend architecture

Form states are a separate topic that needs to be discussed. There are two approaches to handling form states. One of them gives control over the state to the form itself, while the other involves storing it in the user's application. Both approaches have their pros and cons, and these need to be taken into account when choosing one solution or another.

React's documentation calls these approaches controlled and uncontrolled forms. These names are quite an accurate description of what's happening, so we'll use the same terminology here.

Uncontrolled forms

This is an approach where the state of a given form is stored within the form itself and is retrieved only when it is submitted. This is the usual way of working with forms outside of frameworks:

form.addEventListener('submit', (e) => {
  const formData = new FormData(;
  // Data processing, e.g., sending data to the server

The advantages of this method include:

  • Simplicity. There's not much code and there's no need to store the state.
  • Speed. The browser does all the work itself. Minimum intervention required from user code.

Although it's easy and obvious, this approach has one drawback. This approach makes it impossible to respond to changes in the form as it's being filled out. Where might it be needed? Here are a few examples:

  • Autoduplication. Drop-down lists depend on what was typed.
  • Input validation while text is being typed. Often implemented as a red frame around the input box.
  • Instant filtering. This is often used on reservation or product search services. All you need to do is select a menu item, and the available selection will change.

In this situation, we need controlled forms.

Controlled forms

With this approach, the state of all form elements is tracked by the application code. Any change is analyzed and saved. Depending on the current state of the data, the code decides what to show and what not to show. These forms often don't even have a submit button. Especially when forms carry out data filtering.

const state = {
  registrationForm: {
    state: 'valid',
    data: {
      name: '',
      email: '',
    errors: [],

const watchedState = onChange(state, (path, value) => {
  if (path === 'registrationForm.state') {
    if (value === 'invalid') {
      // Rendering errors stored somewhere in the state
      // watchedState.registrationForm.errors
});'change', (e) => { =;
  // Actions: validation, queries, ...
});'change', (e) => { =;
  // Actions: validation, queries, ...

If you need to submit this form, it'll be much easier to do so than with uncontrolled forms. The data has already been extracted from the form and is ready to be sent.

form.addEventListener('submit', (e) => {
  // Data processing, e.g., sending data to the server

The advantages of this approach:

  • It allows you to implement any reaction during a form change before submitting or instead of submitting it.

And its flaws:

  • There's significantly more code if you implement it manually.
  • They're slower because of the greater number of actions (and possibly intensive reactions). But whether it's a problem or not depends on the specific situation.

Controlled forms require so much more code that people try to automate them in every way possible. Libraries have been created, such as garlic.js, that automatically track form changes and provide callbacks to react to those changes.

There are very many of these libraries available for different frameworks. React, for example, has dozens of them.

What should you use?

In pure JS, unsupervised forms are preferred. It's so much easier and faster. And you can still introduce controls for form data if you need an instant reaction. It's not really a binary choice between one or the other, either. You can use a hybrid approach, introducing controls for data only when you can't do without it.

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
hours of theory

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:">Bookmate</span>
<span class="translation_missing" title="translation missing:">Healthsamurai</span>
<span class="translation_missing" title="translation missing:">Dualboot</span>
<span class="translation_missing" title="translation missing:">Abbyy</span>
Suggested learning programs
Development of front-end components for web applications
10 months
from scratch
Start at any time

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.