Skip to content
Swizec Teller - a geek with a hatswizec.com

Why react-hook-form is my new favorite form library

Forms are fun. They start simple then blow up in your face.

You've seen this pattern in every React tutorial with form fields:

Click through for source
Click through for source

Click through for source
Click through for source

A controlled input. Gets value from state, updates value on change. Works great πŸ‘

Keeping form values in state is convenient for business logic. You trigger a re-render for every keypress but that's okay, React is fast.

Then you add more fields ...

Click through for source
Click through for source

Click through for source
Click through for source

That sure blew up πŸ˜…

State up the wazoo, re-renders on any field change, and you haven't even thought about validation, error states, dirty states, and all the rest that goes into a form.

You're smart and you can make this work. I know you can {{ subscriber.first_name | truncatewords: 1, "" | capitalize }}.

But imagine a monster form like I was dealing with last week.

Click through for source
Click through for source

πŸ˜‡

Custom form generators help

You can build a form generator to remove the repetitive work.

Helper component, a loop or two, and off you go, right?

Click through for source
Click through for source

Click through for source
Click through for source

Ok I didn't use loops, but you get the idea.

The <Input> component is generic and we pass-in state and setters from above. Then you can add errors, default values, different styles, etc.

You don't want to push state handling into the Input component itself. That's a recipe for pain.

A better approach might be to turn form state into an object and build a reducer.

Click through for source
Click through for source

Click through for source
Click through for source

Your form state lives inside an object – one key per field. You can always see current state and you always know what's going on.

For easy updates you've got the valueSetter method that returns a function to update a single field.

Works great πŸ‘

You're triggering a full re-render for every field change, you don't have validations, no way to show errors, and no way to know when a field is dirty.

PS: dirty fields are fields that changed and the value hasn't been saved yet

loser giphy

react-hook-form makes everything better

react-hook-form solves those problems for you.

It's a hook-based form solution that takes care of:

  • managing state
  • errors
  • dirty fields
  • validations

And minimizes re-renders by avoiding controlled inputs.

Yep, react-hook-form uses the fields themselves to keep state. Pulls it out when you need it.

Here's the example above built with react-hook-form:

Click through for source
Click through for source

State management turns into this:

Click through for source
Click through for source

Setting up a field turns into this:

Click through for source
Click through for source

The register method returns a React ref and sets up the form machinery.

And when you're ready to submit, values come as an object with a key for every field.

love giphy

You get HTML5 validations out of the box. They show up in the errors object. Like this:

Click through for source
Click through for source

Click through for source
Click through for source

By default validations run on change.

And you can change that with a line of code 😍

Click through for source
Click through for source

Add context for more flexibility

Passing errors and registers into every field like above is silly. Too much work.

That's why react-hook-form supports context.

Using the same approach as my Wormhole state management article:

  • create a form
  • put everything in context
  • wormhole to context with a hook

You get form components that magically connect to your form. Register themselves, know about errors, dirty states. Everything 😍

Like this

Click through for source
Click through for source

Click through for source
Click through for source

Every field validates a 2 character minLength and displays its own errors.

Using them in a form looks easy now:

Click through for source
Click through for source

excited giphy

Add Yup for big validations

You've got the machinery to spit out forms now. Small schlep and you're done.

Render a form, pepper it with <Input name="X" /> fields and voila. Happy boss, happy customer, happy you.

And then it's time for real validations. Not minLength or required. Real validations. The kind where lastName is required, but only if firstName is filled in.

gulp giphy

You can add yup for that. react-hook-form supports it out of the box ✌️

Here's the example above that validates you wrote the whole address, but only if you wrote the street name.

Click through for source
Click through for source

To make that happen you πŸ‘‡

Write a Yup schema describing the shape of your data. Bit of an art to it, make sure you don't fall off the deep end with conditional validations. They get tricky.

Click through for source
Click through for source

The Yup docs are okay, not stellar. I recommend tinkering until it works.

Then you tell react-hook-form about your schema:

Click through for source
Click through for source

And change your register call back to vanilla:

Click through for source
Click through for source

And you've got reusable field components that work with any form. Pop them in, set the schema, get validations and error handling and all the rest.

peace giphy

Happy hacking

Cheers,
~Swizec

PS: in my code I went as far as a generic <Form> component that sets up the context provider and <form> element for me.

Did you enjoy this article?

Published on August 3rd, 2020 in Front End, Technical

Learned something new?
Want to become a high value JavaScript expert?

Here's how it works πŸ‘‡

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet πŸ“–right away. After that you'll get thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

Start with an interactive cheatsheet πŸ“–

Then get thoughtful letters πŸ’Œ on mindsets, tactics, and technical skills for your career.

"Man, love your simple writing! Yours is the only email I open from marketers and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. πŸ‘Œ"

~ Ashish Kumar

Join over 10,000 engineers just like you already improving their careers with my letters, workshops, courses, and talks. ✌️

Have a burning question that you think I can answer?Β I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

Ready to Stop copy pasting D3 examples and create data visualizations of your own? Β Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first πŸ’° on the side with ServerlessReact.Dev

Want to brush up on your modern JavaScript syntax?Β Check out my interactive cheatsheet: es6cheatsheet.com

By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❀️