written by primehammer

React Hooks and Forms

The React community recently announced a new feature Hooks, and in this article we will focus on Forms with hooks and its benefits.

If you haven’t heard about hooks yet, first read Hooks at a glance before we jump in.

NOTE: Hooks are still not available in a stable version and this article is based on version: v16.7.0-alfa.0

Let’s start with refactoring simple controlled form from react docs with name and submit:

See the Pen Controlled Text Example by Petr Heralecký (@melounek) on CodePen.

To refactor the code with hooks we have to:

  • convert class component to functional one
  • state doesn’t exists anymore, so value is not stored in this.state.value but in it’s own variable which came from useState(‘Initial name’ )
  • the first parameter initializes the value
  • methods handle* stay on the same spot

See the Pen Form with React Hooks by Petr Heralecký (@melounek) on CodePen.

Voilà – there we have Hooks based form, without lifecycle methods, but with the same functionality.

For more fields you can write your own useState() for every field, or use one object (recommended) like this:

const [values, setValues] = React.useState({
  name: '', 
  surname: ''
})

Stateful logic with custom Hooks

With Custom Hooks, you can isolate state logic out from the component.

Let’s take a look at a custom hook useNameFormState():

See the Pen Form with React custom Hooks by Petr Heralecký (@melounek) on CodePen.

Keep in mind: hooks can only be used on the top level of any react component or inside custom-hooks.

Since we have now isolated the state logic, it can now be used anywhere, however, it will not share the state itself. This means you can create new state and it’s logic again and again, but state will stay separate for every import.

If you need to share state (values) of form in some other component in your app, you can use Redux (which uses context) or context-api on your own. Let’s look at a “bonus example” below, how you can do a context-based form using hooks.

Form based on the useContext hook

To switch from a state-based, to a context-based controlled form, we will be using useContext (instead of useState).

In the live example below, I also handled error validation to make this example closer to reality. Let’s look at the live example, and I will explain it’s parts below.

See the Pen Form with React useContext hook by Petr Heralecký (@melounek) on CodePen.

Firstly I defined context:

const MyContext = React.createContext();

I want to use this context for more components in my App, so I created an abstract custom-hook useMyContext(section, init) which returns [data, setData]

  • section – unique name for specific component (form)
  • data – actual data from the context
  • setData – function passing updated data into it’s section in context

useNameForm() is the provider of context-data and actions which returns:

  • data – the data-object from context
  • and actions changeValue, setErrors, etc… – which are updating these context-data

If you expect, there will be only one form-component using the context in our app, you can join useNameForm and useMyContext into a single custom-hook.

Conclusion

Ok, so there it is. I know, the last one was rough, but we made it. Now you know how to create a simple controlled form using useState hook, how to isolate it’s state-logic by creating custom hook, and finally, how to switch from state-based to context-based form.

Using context could be useful, if you are looking for full control of your form-data across the entire application, but of course, there are other possibilities of handling form data-globally, like with redux-form or redux directly.