Hacker News new | past | comments | ask | show | jobs | submit login

I've never seen a benefit in storing a form state in react state, forms already hold a state in the DOM, you can read, update and validate it (https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Fo...)

for example, after a form submit event, you can do

  const elements = [...e.target.elements].filter(el => el.name); // all form elements with a name
  // invoke onSubmit prop with form data:
  onSubmit(
    elements.reduce((o, el) => ({
      ...o,
      [el.name]: el.type==='checkbox' ? el.checked : el.value
    }), {})
  );





Part of the point (from a React perspective) is that everything in a React UI is driven by the data - so your data (state) should always control the UI.

If you store some state in JS variables, and some in the DOM (forms), then that's not true anymore. That's not necessarily a problem if you're expecting it (uncontrolled components are a valid React paradigm) - but if you're expecting controlled components, but some of them aren't, then you can run into trouble.

Also, once you're used to controlled components, it actually feels like a hassle to keep the data in the DOM - you have to constantly be getting it from the DOM to do form validation, submitting, field resetting, etc.

Again - I would say that neither is more right or wrong; but it's more of a style choice.


This is a really good reply! In fact, React hook form is based on uncontrolled components, I guess the mainstream is still controlled, but I would like to give some fo the love to uncontrolled and explore the benefits from it.

import React from 'react'; import useForm from 'react-hook-form';

function App() {

  const { register, handleSubmit, errors } = useForm(); // initialise the hook

  const onSubmit = data => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="firstname" ref={register} /> {/* register an input */}
      
      <input name="lastname" ref={register({ required: true })} />
      {errors.lastname && 'Last name is required.'}
      
      <input name="age" ref={register({ pattern: /\d+/ })} />
      {errors.age && 'Please enter number for age.'}
      
      <input type="submit" />
    </form>
  );
}

here is an code example, there is no local state.


The whole point is decoupling Dom state and Application state, React keeps the two in sync via the reconciler, and you as the developer can have a single source of truth. As application complexity grows it gets difficult to make sure your DOM and your javascript are in sync using element objects.

That said Forms are one thing where I don't understand all the libraries built to 'simplify' them. They are not complex, and trying to force the library to fit your use case usually ends up being more burdensome than just writing the extra 20-30 LoC.


Having it in state allows you to react to changes in the form fields for validation, i.e. username availability, password strength, email validity, field character length (think twitter), etc.

Of course you can do this imperatively by manually querying the DOM and getting the input values, but I think it's nice to have the form data in the state to work with and have full control over it.


That’s it! React hook form is basically doing that :) it’s uncontrolled.



Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: