-
Now that we decide to include user auth as part of new Blitz apps, we need to also include a default form library because we'll have multiple forms by default. The top options are formik, react-final-form, and react-hook-form FormikFormik used to be my default form library of choice until I realized it has very bad perf problems for anything beyond very simple forms. There's a rummer that it's being converted to use subscriptions (like react-final-form), but 🤷 So I think our decision should be between react-final-form and react-hook-form React-final-formReact-final-form has been my default for awhile now. I've used it on multiple projects with great success. It's super robust, blazing fast, and extremely powerful, including a really nice plugin system for things like persisting form state to local storage. Our auth example app currently uses react-hook-form, so you can see it in use. React-hook-formI've never use react-hook-form on a full project, but I did convert the auth example app to use react-hook-form. See the code diff between react-hook-form and react-final-form in the auth example. The diff between react-final-form and react-hook-form is mostly trivial. A few things are different, but not much. That said, I really do prefer the API of react-final-form and think it's the best default option for Blitz. Keep in mind, that we can always re-evaluate this later, and once we have recipes we can add a prompt that allows people to choose different options during new app creation. |
Beta Was this translation helpful? Give feedback.
Replies: 13 comments 17 replies
-
i’m in favor of react hook form (vs final forms cause I dont like formik), not by much but I think the API is simpler: there is no render props which I find harder to deal with, specially for juniors, hooks are easier, they are more readable/understandable quickly, the docs are great, and for 95% of use cases it will do the job |
Beta Was this translation helpful? Give feedback.
-
I’ve used neither (only used Formik) but from the looks of it I think I agree with @goldo. The hooks api looks slightly better and more understandable to me. That said, I have no hugely strong feelings one way or the other. |
Beta Was this translation helpful? Give feedback.
-
I am not a fan of Render Props. I don't know much about final-form, except that it was originally written to be Framework agnostic. I don't think that is a value that Blitz cares about. I would see it as a down-vote. I have been using react-hook-form and I quite like it. It's only a year old, and is a react hooks FIRST approach to forms. Lots of updates, low open issue count. Very good docs. Also has Dev Tools
Therefor react-hook-form gets my vote :-) |
Beta Was this translation helpful? Give feedback.
-
My vote would be react-hook-form. I haven't used react-final-form much, but I was a heavy user of redux-form, which a lot of the API is derived from, and it was probably the most significant hurdle when we brought non-React devs to work on our React components. We had to develop a lot of "tribal knowledge" about the correct way to structure forms to fit our needs and avoid issues with state updates happening in the wrong order or calculating the wrong final state. Looking at the FAQ I'm seeing questions/answers that remind me of the kinds of "tribal rules" that we had to come up with for redux-form. Plus the appearance of a |
Beta Was this translation helpful? Give feedback.
-
I'll also toss a vote for react-hook-form. I've been using it in all my projects lately and it has been (mostly) a joy to use. |
Beta Was this translation helpful? Give feedback.
-
One of the things that turns me off the most about hook-form is that as soon as you need a controlled component (and you will if your app is of any size or uses a lot of third party components) you have to use the alternative react-hook-form https://react-hook-form.com/get-started#IntegratingwithUIlibraries import React from "react";
import Select from "react-select";
import { useForm, Controller } from "react-hook-form";
import MaterialUIInput from "@material-ui/core/Input";
import { Input as AntdInput } from "antd";
const App = () => {
const { control, handleSubmit } = useForm();
const onSubmit = data => {
console.log(data)
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
as={MaterialUIInput}
name="firstName"
control={control}
defaultValue=""
/>
<Controller
as={AntdInput}
name="lastName"
control={control}
defaultValue=""
/>
<Controller
name="iceCreamType"
as={Select}
options={[
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" }
]}
control={control}
rules={{ required: true }}
/>
<input type="submit" />
</form>
);
}; That means you have two different hook-form APIs you have to know and use. But with react-final-form, you use the same So either way, you'll likely have a render prop. I definitely agree the primary API shouldn't be a render prop, but looks like it's impossible to 100% avoid render props. I think the whole dance to avoid controlled components by passing refs to everything just unnecessarily complicates everything, especially when a subscription implementation like final-form gives you the same high performance with controlled components. An example of this is when you need to add your own ref to a component for doing imperative focus or something. Now instead of doing the normal const { register, handleSubmit } = useForm();
const firstNameRef = useRef();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="firstName" ref={(e) => {
register(e) // hook-form register
firstNameRef.current = e // manually assign your ref
}} /> Also hook-form has subtle UX things with validation that is sub-par. With hook-from you set the validation mode of So the optimal flow which you get with final-form is this:
|
Beta Was this translation helpful? Give feedback.
-
I mostly worked with |
Beta Was this translation helpful? Give feedback.
-
I've only used |
Beta Was this translation helpful? Give feedback.
-
Something else to keep in mind is that we aren't necessarily optimizing for beginners. I think we are optimizing for the long-term pit of success. In other words, when possible we want to minimize the situations where a year or so after starting, Blitz devs have to replace a part of the app that came by default with a new Blitz app.
This default that we are deciding here is also what will be the "recommended" choice once we add multiple options to |
Beta Was this translation helpful? Give feedback.
-
react-hook-form has been my go-to solution for the past year. It's much nicer to use than Formik. It's very simple for small forms, but also provides APIs to have full control over your form. I especially like that they provide examples for many complex use cases. I haven't tried react-final-form. As far as popularity goes, both are widely used, but react-hook-form seems to be getting more traction (see the chart) |
Beta Was this translation helpful? Give feedback.
-
I am changing my vote to |
Beta Was this translation helpful? Give feedback.
-
I've used Formik, react-final-form, and react-hook-form. react-hook-form was a much nicer experience than the others. I found react-final-form to get unwieldy very quickly. I was hoping react-final-form to be an improvment over Formik but that was not the case for me. react-hook-form is now my go-to solution for forms as well. |
Beta Was this translation helpful? Give feedback.
-
Well, since recipes are now working we can launch with both react-hook-form and react-final-form as options! Debate resolved 😇 |
Beta Was this translation helpful? Give feedback.
Well, since recipes are now working we can launch with both react-hook-form and react-final-form as options! Debate resolved 😇