16 ms·
Show HN: React Hook Form – Simple Form Validation
- bluebill1049 7y agoHi guys, I have built a custom hook for form validation, please check it out and feedback welcome <3
- latchkey 7y agoThis looks great. How about a comparison against https://final-form.org/react https://final-form.org/react ?
- bluebill1049 7y agoSure I will looking into it and add to the comparison.
- latchkey 7y agoGreat thanks. One other helpful thing would be to start a project full of pre-wrapped components for various frameworks. It would be lovely to just yarn add something that would give me Material-UI components already set up. I'm sure others would love a Bootstrap version... etc. The more you can lower the barriers to entry, the better.
- bluebill1049 7y agoThat sounds like a great idea! Maybe I should set up some quick templates.
- bluebill1049 7y agoBy the way I did have a folder of examples as well. Quite lot of them: https://github.com/react-hook-form/react-hook-form/tree/master/examples https://github.com/react-hook-form/react-hook-form/tree/mast... with codesandbox link too
- latchkey 7y agoSure, I've seen examples, but that is different than what I'm talking about. I want components. =) For example, with react-final-form, I wrote a thin wrapper for Material-UI component (example [1]). While it didn't take me that long to do, it does have some weird edge cases that I had to google around for. It would be nice to not have to figure this stuff out with your framework too and would encourage me to try it out more quickly. I know that formik and redux-forms are popular, but react-final-form and your framework seem to have a lot of overlap. Both seem to be pretty well done. [1] https://gist.github.com/lookfirst/558fb2161fd633c7eaab412b851f1c19 https://gist.github.com/lookfirst/558fb2161fd633c7eaab412b85...
- bluebill1049 7y agosounds good. i will be looking into that :)
- zuck9 7y agoLanding page is pretty impressive. Nice work :)
- bluebill1049 7y agoThank you. I was try to giving everyone some good context why built this form lib.
- helb 7y agoI've been playing with it for the past ~40 minutes and i really like it. Can't wait to use it on a real project soon. In fact, i might start converting some older things to it in spare time. The website and docs are absolutely amazing, best i've seen in a long time. Thank you for doing this!
- bluebill1049 7y agoThank you so much for those kind words. This means so much to me seriously. I love making things and especially when others are enjoy to use. I will keep improving the site and package. Feel free to ask questions in github :) again thank you <3
- 11235813213455 7y agoI'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/Form_validation 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 }), {}) );
- bluebill1049 7y agoThat’s it! React hook form is basically doing that :) it’s uncontrolled.
- bluebill1049 7y agoimport 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.
- chrisa 7y agoPart 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.
- CGamesPlay 7y agoThis looks really good. But is there a non-hook version for use in class components? I'm imagining it might look like this: class MyForm extends React.Component { formState = new ReduxHookForm(); render() { const { register, handleSubmit } = this.formState; return ( <form onSubmit={handleSubmit(this.handleSubmit)}> <input name="firstName" ref={register} /> <select name="gender" ref={register}> <option value="male">male</option> <option value="female">female</option> </select> <input type="submit" /> </form> ); } handleSubmit(data) { console.log(data); } }
- bluebill1049 7y agoyea would be similar for class component :)
- CGamesPlay 7y agoSorry I don't understand. Last time I checked, hooks are not usable from class components. How can I use react-hook-form from a class component?
- bluebill1049 7y agoSorry I meant once I made it work, and it will be the syntax
- bluebill1049 7y agoI haven't got a plan to look into class component just yet, but will do in the near future.
- franciscop 7y agoI have a pure-javascript library that works like that, "forn". No hooks or any local state needed: https://www.npmjs.com/package/forn https://www.npmjs.com/package/forn
- ozgrozer 7y ago
- softwarelimits 7y agoI strongly recommend to automate form generation based on JSON schema what will enable zero coding for maintenance tasks like e.g. synchronization with model changes. As form code is the most important entry point for security flaws in web applications it is also the most expensive and it is not a good idea having to touch production code for every little backend change. This looks like PHP coding 15 years ago. Do not do that.
- bluebill1049 7y agoeverything is about pros and cons. there is no silver bullet for building form if you enjoy building a form with JSON schema good for you too. Thanks for checking it out tho :)
- throwaway_bad 7y agoCan you point to a real world example of what you mean? I think I have heard of something similar but it didn’t seem to have caught on in any major web frameworks that I know of (strongly typed json API server which generates runtime validators on frontend and backend). Even then most people want control over the presentation of the form and wouldn’t want to create fields from the schema (e.g. a number type is sometimes a slider and sometimes a drop down)
- tiborsaas 7y agoA friend of mine build a solution like this: https://laraform.io/ https://laraform.io/ If I have a form anything more complex than a login page, then I usually use some kind of generator based on a schema.
- bluebill1049 7y agointeresting project! thanks for sharing
- mickael-kerjean 7y agoThere's a few people trying to build libraries (https://github.com/rjsf-team/react-jsonschema-form https://github.com/rjsf-team/react-jsonschema-form) but there ain't any magic bullet. For this project (https://github.com/mickael-kerjean/filestash https://github.com/mickael-kerjean/filestash), I built my very own as no other library would work for what I wanted
- franciscop 7y agoHey author I like this! It's very close to what I use for simple forms, my library `forn`: import forn from 'forn'; export default () => ( <form onSubmit={forn(data => console.log(data))}> <input name="firstName" placeholder="First Name" /> <input name="lastName" placeholder="Last Name" /> <button>Send!</button> </form> ); Test it: https://codesandbox.io/s/agitated-johnson-3hv96 https://codesandbox.io/s/agitated-johnson-3hv96 Why do you need the register though? Is the hook needed to hold the refs? Is it only for compatibility with React Native or are there other reasons? With forn I use `e.target`, which should not be available in RN.
- bluebill1049 7y agohey, nice lib you got there :) When I was deciding the API, I did have the idea of just collecting form input automatically (similar to forn), but there are few reasons which lead to the final decision: 1. Support React controlled component. eg some of the popular component libs, they are wrapped input inside their component and it's hard to predict which to include during the form submit. 2. React Native <3 3. Attach validation rules, messages and async validation on the individual field level.
- franciscop 7y agoHa thanks! You described perfectly the limitations of `forn` and why I only use it for simpler forms. React Native is a big pain from tine to time though I barely use it. I also made https://picnicss.com/ https://picnicss.com/ so I'm used to use the native form elements underneath and the rest being just a pretty wrap. But yeah, as soon as I add a 3rd party form lib all goes to hell and `forn` doesn't work well anymore. I'll try it next time I have to deal with React Native!
- bluebill1049 7y agowow so cool~ https://picnicss.com/ https://picnicss.com/ love it. stared the project. <3
- riccardogiorato 7y agoLove this! I will write a small tutorial on it and I will use it too to make forms better!
- chatmasta 7y agoI’ve been using this for the past few weeks and I’m very happy with it. I really appreciate the minimalism. It’s easy to have schema driven forms and uncontrolled inputs with this library because it doesn’t have many constraints. Also, maybe it’s because of hooks, but it feels like less code than usual is required for forms. I once built a massive “multi page questionnaire with conditional logic” feature, using a superset of json schema and a wrapper around react-json-schema-form (the Mozilla one). That was two years ago and a LOT of code (I used a singleton controller to parse local updates and merge them into a global schema). If I had hooks and this library available then, it would have been significantly less code.
- bluebill1049 7y agowow thanks, chatmasta, I am really glad to hear this great feedback! I would like to put the credit towards React Hook because it really saves us to write less code and not to worry too much about the lifecycle methods.
- Touche 7y agoFront-end has gone completely off the deep end. I'm looking at the source code and there must be 4 or 5 dozen modules, totally 5.1kb gzipped! And as far as I can tell all it does is copy el.value onto an object. What ever happened to care in our profession? What happened to putting the users first? If you are adding 5kb of overhead to your website for this, it is criminal malpractice.
- armatav 7y agoMate most websites are shoving MBs down your throat, I’ll gladly take 5kb zipped for a better developer experience.
- Touche 7y agoIf doing `obj.firstName = el.value` is too bad of an experience for you that you need to add 5kb to make it better you're going to get to that MBs pretty quickly.
- bluebill1049 7y agono comment...
- ivanhoe 7y agoThis is like saying that backend's gone crazy because people are loading MBs of frameworks just to print "Hello World" on the screen. Well, yes, but those are just examples, they're meant to be simple to understand, not a realistic use case. React is a tool for building complex web apps and in RL such app would do a lot more things and then it'd start to make a lot more sense using it. If you do something this simple, then by all means don't use it.
- Touche 7y ago> This is like saying that backend's gone crazy because people are loading MBs of frameworks just to print "Hello World" on the screen. They are not equivalent at all, you can add as much bloat as you want on your backend as long as you scale it. The cost is put on you. Front-end bloat directly affects the user. We used to justify every library addition, now people just add a library for every trivial task to make it slightly "nicer" as if that matters at all.
- erikpukinskis 7y agoI’m going to hijack to request some help understanding whether hooks are a good thing or.... a mediocre thing I just have to accept. Here are my questions: 1) Is it just me or so hooks really push you to commit to either “state comes from props” or “state is held internally” but you REALLY can’t mix the two? So, if I have say, a searchable select box, I must either A) be stateless, and let some other part of the system store the user’s typing, or B) use a state hook, but NEVER react to state changes coming in from outside. I.e. I am tempted to use useEffect to notice my props and my state being out of sync so I can sync them back up, allowing either the user or the backend to provide changes. But that also feels bonkers. Doing the same thing through message passing also seems bonkers, React was created to replace having to pass messages around to every component that needs updates, wasn’t it? 2) Is there any point to useCallback? Is it literally the same thing as returning a function from useMemo? 3) Is it just me or is useRef kind of a horrible hack? Lots of articles tell me to do myRef.current = myState in order to hack around the fact that state changes don’t take effect until the next tick. But now we no longer have a single source of truth, and introduce lots of sync bugs. Also have to type .current everywhere. 4) Should I be using useEffect instead for solving the issue with #3? I just have this sinking feeling that at least one of useRef, useMemo, useCallback, and useEffect shouldn’t exist, but I am only three months in to React and I can’t really see the forest through the trees.
- darcien 7y ago1) You could mix the two around. E.g. using a state hook and the imperative handle hook. By using the imperative handle, we could update the state from the outside by exposing the setState function. 2)There are several points, but I think the most important one is simply just to save time instead of using useMemo as passing callback to child components is pretty common. And yes, it is the same. The official docs literally said that. useCallback(fn, deps) is equivalent to useMemo(() => fn, deps). [0] 3)You can call it a hack I guess. If you don't want to wait for rerender, you can keep a value inside a ref! While class component can just create a property, function component doesn't have that. That's where the useRef came in, and that's just one use of useRef. I'm not really sure about the articles you mentioned. I never faced a use case where you would use a state and also keeping it inside a ref, can you share an example link maybe? For the .current part, since refs is originally used to access the DOM. And the DOM node could change for whatever reason. To access the node, we use .current. 4) It depends, but I don't think keeping two things in sync using useEffect hook is a good idea. I'm not really clear about the issue, so I can't say much. After using React for a while with class and lifecycle, I think all the available hooks is really nice. Feels like we got a fresh wind while developing with React. Using hooks and not have enough contrast to make me feel I can no longer code React without hooks. They let you reuse and share the same logic for different components or projects easily. Less code to read, and for me, functional component with hooks is way easier to read compared to a class component. Refs: [0] https://reactjs.org/docs/hooks-reference.html#usecallback https://reactjs.org/docs/hooks-reference.html#usecallback
- byahya 7y agoHey author, I’m a long time reader and this is my first post on here! That being said, I absolutely LOVE your library! I’ve been working on a project for a client (a react webapp). I initially built out our signup workflow and delayed completion on that feature until the very end of the app simply because custom validation was a pain (and with tight deadlines, I really didn’t want to write one from scratch). I came across your library about two weeks ago and it fit like a GLOVE! Custom validation was easy, adding in regex expressions was straightforward, and your docs are very clear! Kudos for this project, you’ve made my life much easier. My app happened to also be built entirely with react hooks so this really was a great fit. And the dependency size is much smaller than competitors I was looking at. Thanks for your hard work I definitely appreciate it!
- bluebill1049 7y agoThank you very much byahya for your kind words and the lovely message. I am really glad could help you out with building forms. This is also one of the reasons why I am so passionate about building open source projects, be a dev only also me to solve particular within a product or project. it's so good we have an amazing community who are sharing their idea and code around the world. It's my 2 cents to give back the community and help out others and of course doing something meaningful in my life :) I really appreciated your feedback and your encouragement, feel free to ask a question or submit issues in the GitHub. <3