DEV Community

Cover image for React Forms — Formik vs. Hook-Form vs. Final-Form

React Forms — Formik vs. Hook-Form vs. Final-Form

Sm0ke on April 14, 2022

Hello Coders! Forms are a crucial part of every application, from signing up, logging in, or collecting a survey from our users. Forms may seem s...
Collapse
 
hunghvu profile image
Hung Vu

The choice of validation tool sure depends on your choice of UI library. If I want to bootstrap a project with controlled components as fast as possible, then Formik is a great choice. However, it really does not scale well with complex form.

React Hook Form was born to solve the performance problem, but well, making it maintainable with external controlled components is a nightmare. God forbids me when I use React Hook Form with MUI, on a form that has ~100 fields or more.

It is a trade-off I would say, and apparently, there is no solution in-between that is a jack of all trades.

Collapse
 
brianmcbride profile image
Brian McBride • Edited

I realize it is a pain, but you can just create a higher order component for MUI components to make React Hook Form "just work". But, you only have to do it once. Then you can have a FormTextField to use instead of just the TextField.

A quick search pulled up this open source code: github.com/dohomi/react-hook-form-mui
There migh be better, honestly I just rolled my own when I was using React Hook Form. But this is a solid example.

Collapse
 
sm0ke profile image
Sm0ke

Noted also.
🚀🚀

Collapse
 
sm0ke profile image
Sm0ke

Ty for your feedback Hung.
Totally agree with you.

Collapse
 
techsaq profile image
Mohd Saquib

Can you please provide more details why not to use react hook form with MUI as i am thinking to use these two.

Thanks

Collapse
 
hunghvu profile image
Hung Vu • Edited

It's NOT about avoiding the usage react-hook-form with MUI. It's more about a complexity of integration when your forms become complex (e.g., 50 fields with conditional choices) should be put into consideration.

MUI uses controlled components (e.g., TextField), which means a component has its own internal state (not controlled by the DOM). Indeed, <input> is used underneath and its properties are exposed via inputProps. The great thing about Formik is it can directly work with controlled components. Here is an example of Formik with MUI: formik.org/docs/examples/with-mate....

react-hook-form is more complicated to setup in the long run. react-hook-form by design targets as native and uncontrolled components. It has Controller to help work with external controlled components from libraries like MUI. However, ref of internal input of a component must be exposed somehow, which is not always the case (not a must, see Bill's explaination in the thread below). At that point, you will need to find a hacky way to ensure react-hook-form a single source of truth.

You may ask why don't we break down a form to have smaller chunks. The thing is, some forms have tightly-coupled sections by nature (U.S tax form for example). Breaking it down will result in other set of problems, such as global state control, and can even be more complicated.

Hope this helps!

Collapse
 
brianmcbride profile image
Brian McBride • Edited

After a while, I ended up stopping use of any of these libs.

For a while, I was using a lib called Hookstate.js hookstate.js.org/
It is a very clever lib. It has great performance in updating child components. I built a set of higher order components to my UI library. I could just pass into a field a scoped state as documented here: hookstate.js.org/docs/scoped-state. It looked like this in use:

const state = useState({
    email:  '',
    password: '',
});
Enter fullscreen mode Exit fullscreen mode
<StateTextField
    required
    label="Email Address"
    name="email"
    autoComplete="email"
    state={state.email}
/>
Enter fullscreen mode Exit fullscreen mode

This is great. Hookstate will only update the StateTextField on change making huge forms VERY performant. If you ever had to deal with a very large form where an update to one field causes a redraw on all, you'll know what I mean. Unfortunately, PRs and Issues are piling up with Hookstate. Sadly, the maintainers might have less interest in keeping things updated.

I'm currently giving Zustand a go github.com/pmndrs/zustand
It is a very small library, less than 1kb.
The goal is to use it as a form validation lib as well as handle my other global state needs.

I am adding a form wrapper like to Zustand like: github.com/Conduct/zustand-forms is what I am looking to do. If you look at the source in this repo, you'll see that it just isn't that much code.

<TextInput
  value={formValues.password}
  onChange={(v) => updateInput({inputId: 'password', v})}
/>
Enter fullscreen mode Exit fullscreen mode

You could make it more complicated by tracking the ref and id of the component and auto matching that with your data object. That code snipped seems ok though, even with a larger or dynamic form.

Of course, your own wrapper might be like what I did with Hookstate where I pass it in a state reference and use the component's name or id to map to the state's field name.

So, now I have zustand (which has use-sync-external-store as a dep), zustand-forms (which has immer as a dep). I'm at 4 libs. You could probably refactor not to use immer as well. The point is, if you are like me and use some global state tooling (whatever it is), the form libs become just another item to pile on the stack. The whole solution likely being under 2kb. Of which most of that was going to be in my code anyway.

Collapse
 
sm0ke profile image
Sm0ke

Hello Brian & ty for you feedback.
Zustand looks good, I will take a look.

Collapse
 
calag4n profile image
calag4n

I've once used react-hook-form on a pretty big web app project .
At first, I've found it fun but when forms become large, complex and dynamic, we've seen it's limitations, many troubles, bad experience... Then we switched all app to Formik.

And since then, if I need strong and reliable forms I use Formik.
So, my advice is : be careful with react-hook-form !

Collapse
 
uithemes profile image
ui-themes

Thanks for writing!
Size is not a super problem. I'm using Formik and probably stick to it for a while.

Collapse
 
sm0ke profile image
Sm0ke

🚀🚀

Collapse
 
crearesite profile image
WebsiteMarket

React Final Form code looks cleaner.
Thanks for sharing!

Collapse
 
sm0ke profile image
Sm0ke

🚀🚀

Collapse
 
bluebill1049 profile image
Bill

Thank you for writing this length and detailed comparison! ❤️

Collapse
 
sm0ke profile image
Sm0ke

Yw Bill!
🚀🚀

Collapse
 
sm0ke profile image
Sm0ke

Hello Luke & Ty for your note.
🚀🚀

Collapse
 
admindashboards profile image
admin-dashboards

wow ...

Collapse
 
sm0ke profile image
Sm0ke

ty!
🚀🚀

Collapse
 
swaniyah profile image
❄ Saamiyah ☼ • Edited

Which one would you recommend for scalable forms where performance is an important factor.

Collapse
 
sm0ke profile image
Sm0ke

React-Hook-Form ...
Thanks for reading Saamiyah

Collapse
 
brense profile image
Rense Bakker

Formik also provides hooks if you prefer that pattern

Collapse
 
jd82 profile image
jd

After all these comparisons If I start any project right now, I’ll choose React-Hook-Form, because it has zero dependencies and less boilerplate code compared to React-Final-Form and Formik.
Formik and React-Final-Form make forms complicated while React-Hook-Form looks cleaner and more intuitive at first look. Also, the validation provided by React-Hook-Form uses less code to finish the job.

Really? It came down to having slightly less code and "looks" more intuitive? When you make a comparison article like this, people expect you to have used 2 or more of these libraries for months on end to get a grasp of where each one shines, encountering edge cases, etc.

This is a silly article.

Collapse
 
aaravrrrrrr profile image
Aarav Reddy

Cool!