Advanced

Menu

Accessibility (A11y)

React Hook Form has support for native form validation, which lets you validate inputs with your own rules. Since most of us have to build forms with custom designs and layouts, it is our responsibility to make sure those are accessible (A11y).

The following code example works as intended for validation; however, it can be improved for accessibility.

After this improvement, the screen reader will say: “Name, edit, invalid entry, This is required.”

Wizard Form / Funnel

In this video tutorial, I have demonstrated the core concept of how to build multiple steps funnel with React Hook Form.

It's pretty common to collect user information through different pages and sections. We recommend using a state management library to store user input through different pages or sections. In this example, we are going to use little state machine as our state management library (you can replace it with redux if you are more familiar with it).

With the Form component injecting react-hook-form's props into the child component, you can easily create and compose complex forms in your app.

Field Arrays

This is one of the best features about React Hook Form: instead of importing components (like other libraries) to achieve this functionality, you can leverage your existing HTML markup. The key is within the name attribute. In React Hook Form, the name attribute represents the data structure you want to use.

Note: we have also built a custom hook for complex scenario: useFieldArray.

The following example demonstrates how you can create Field Arrays by manipulating the input name attribute.

Schema Validation

React Hook Form supports schema-based form validation with Yup, where you can pass your validationSchema to useForm as an optional config. React Hook Form will validate your input data against the schema and return with either errors or a valid result.

Error Messages

Error messages are visual feedback to our users when there are issues with their inputs. React Hook Form provides an errors object to let you retrieve errors easily. There are several different ways to improve error presentation on the screen.

Register

You can simply pass the error message to register, via the message attribute of the validation rule object, like this:

Optional Chaining

The ?.optional chaining operator permits reading the errors object without worrying about causing another error due to null or undefined.

errors?.firstName?.message

Lodash get

If your project is using lodash, then you can leverage the lodash get function. Eg:

get(errors, 'firstName.message')

Connect Form

When we are building forms, there are times when our input lives inside of deeply nested component trees, and that's when FormContext comes in very handy. However, we can further improve the Developer Experience by creating a ConnectForm component and leveraging React's renderProps. The benefit of such a component is you can connect your input with React Hook Form from anywhere.

FormContext Performance

React Hook Form's FormContext is built upon React's Context API. It solves the problem where data is passed through the component tree without having to pass props down manually at every level. This also causes the component tree to trigger a re-render when React Hook Form triggers a state update, but we can still can optimise our App if required via the example below.

Conditional Controlled Component

React Hook Form makes dealing with conditional fields really simple because when you remove the input from the component tree, it will get unregistered automatically. Here is an example for such behavior. However, that's not the same case for controlled components since ref is not been registered, and we can do the following:

Import Controller to wrap your component and let it manage register and unregister

Controlled mixed with Uncontrolled Components

React Hook Form embraces uncontrolled components and is also compatible with controlled components. Most UI libraries are built to support only controlled components, such as Material-UI and Antd Besides, with React Hook Form the re-rendering of controlled component is also optimized. Here is an example that combines controlled and uncontrolled form validation.

Working with virtualized lists

Imagine a scenario where you have a table of data. This table might contain hundreds or thousands of rows, and each row will have inputs. A common practice is to only render the items that are in the viewport, however this will cause issues as the items are removed from the DOM when they are out of view, and re-added. This will cause items to reset to their default values when they re-enter the viewport.

To work around this, you can manually register the fields, and then programatically set the value of the field.