DEV Community 👩‍💻👨‍💻

Max Anselmo
Max Anselmo

Posted on

Strange Bugs 1: The Fussy Controlled Form

Welcome to Strange Bugs!

In this post I will go over a bug I encountered while creating a controlled form in the app I'm working on.

Here is the layout for the component I was building:

const Card = () => {
   const [showFront, setShowFront] = useState(true)
   const [formData, setFormData] = useState({
      input1: value1,
      input2: value2,
      ...
   })

   function handleInputChange(e) {
      const name = e.target.name;
      const value = e.target.value;
      setFormData({ ...formData, [name]: value });
   }
   ...

   const CardFront = () => {
      return <form>
         <input name="input1" value={formData.input1}
         <input name="input2" value={formData.input2}
         ...
         <button>Submit</button>
      </form>

   }

   const CardBack = () => {
      return <div>
         <p>{formdata.input1}</p>
         <p>{formdata.input2}</p>
         ...
      </div>

   }

   return (
      { showFront ? <CardFront /> : <CardBack />
   )

}
Enter fullscreen mode Exit fullscreen mode

The Bug:

When attempting to type into one of the inputs, I was only able to enter one character, and then I would be tabbed out of the input, and would have to re click the input over and over to continue typing.

The Struggle:

This bug had me stumped for a good few hours, unsure what was causing the issue. After some time, I was convinced there was something going on with the state, as this issue had only came up after I turned the inputs into a controlled form by giving them state.

The Realization:

While taking a look and breaking things down line by line with a fellow peer, we finally discovered what was going on. On each keystroke while typing in one of the inputs, the state for the formData would be updated in the parent / wrapper component, which would re-render the child component, causing it to forget that we we're writing in one of the inputs.

The Solution:

My hack to fix this, was to simply break the nested components out of themselves, and put the jsx into react fragments instead.

return (
      { showFront ? 
         <> 
            <form>
               <input name="input1" value= {formData.input1}
               <input name="input2" value={formData.input2}
            ...
               <button>Submit</button>
            </form>
         </> 
         : 
         <> 
            <div>
               <p>{formdata.input1}</p>
               <p>{formdata.input2}</p>
               ...
            </div>
         </>
   )

Enter fullscreen mode Exit fullscreen mode

Top comments (0)

Timeless DEV post...

How to write a kickass README

Arguably the single most important piece of documentation for any open source project is the README. A good README not only informs people what the project does and who it is for but also how they use and contribute to it.

If you write a README without sufficient explanation of what your project does or how people can use it then it pretty much defeats the purpose of being open source as other developers are less likely to engage with or contribute towards it.