

Integrating React Hook Form & Redux-Toolkit (rtk)
source link: https://orizens.com/blog/integrating-react-hook-form-and-redux-toolkit-rtk/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Integrating React Hook Form & Redux-Toolkit (rtk)
October 13, 2021

When i’m coding forms with react, I prefer using react-hook-form. I find it simple but yet powerful enough. In of the projects I was working on, the initial form’s data is pulled from a redux store. The requirement for this project is to push the form’s input back to the store - that means, submitting the form results in updating the store.
Some of the data in the store is not reflected in the form, but rather is updated directly with the reducer’s action functions. In addition to that, data in the store may be updated from other sources that are not part of the form.
That means the form’s values need to be updated with the latest data from the store, so updates on the data source should go both ways:
- from store to form
- from form to store
If not done right, these updates may go into an infinite loop which would crush the browser. I have come up with a strategy to make sure this would not happen.
The App with Redux Toolkit and useForm
ReadM includes a book editor and front page editor sections which allow an Editor to create books. This section is implemented with useForm
and Redux-Toolkit.
Book Editor
Front Page Editor
Next, we’re going to create our own custom hook which will use useForm
and is responsible for updating the store or the form when either is changing - without going into infinite loop.
Custom Form Hook
I want this custom form hook to be responsible for any data updates going both ways, and that’s why i prefer to compose the logics inside this custom hook. I wrote before on improving your developer experience custom hooks.
This hook creates an instance of useForm
and invokes 2 additional hooks which are responsible for updating the store and the form when the data changes in one of them. These hooks are actually standalone hooks and require a the useForm
api to perform the update.
export function useBookForm(book: IBook) {
const bookActions = useBookActions(book.id)
const useFormApi = useForm<IBook>({
defaultValues: book
})
const { handleSubmit } = useFormApi
/* Data source updaters */
// update the FORM => WHY? change comes from "book" prop
useFormUpdater(book, useFormApi.setValue)
// update the STORE => WHY? change comes from the "form"
useBookUpdater(useFormApi, bookActions.updateBook)
const onSubmitHandler = useCallback(
() => handleSubmit(bookActions.updateBook),
[handleSubmit, bookActions.updateBook]
)
return {
onSubmitHandler,
useFormApi
}
}
Update Form When The Data source in Redux Store has Changed
The useFormUpdater
hook is using the excellent useDeepCompareEffect
hook which performs a deep equality comparison of the next and previous book object (a complex json object).
When change is detected, the useForm.setValue()
is used to update the form. according to the [use form docs], setValue
is more performant then reset()
by avoiding “unnecessary re-rerenders”. The ‘shouldDirtyproperty is set to
false` because in this case, I don’t want the field to be set as if the change was coming from the form.
import { useDeepCompareEffect } from "react-use"
const useFormUpdater = (book: IBook, setValueToKey) => {
useDeepCompareEffect(() => {
const setValueToKey = ([key, value]: [string, any]) => {
setValue(key, value, { shouldDirty: false })
}
Object.entries(book).forEach(setValueToKey)
}, [book, setValue])
}
Update Redux When The Form has Changed
Next, this custom hook is responsible for watching the form’s changes and updating redux. A naive approach would just invoke the redux action update function with the entire form’s data - this would be prawn to that infinite re-rendering cycle I mentioned at the beginning of this article.
The solution for that is to update the store with the changes only. That means creating a book object with the properties that have changed.
This hook is using the useDeepCompareEffect
to compare the entire book’s form changes. However, in this case, i’m creating the set of changes by filtering the fields that have changed with the useFormApi.formState.dirtyFields
. This is a key/value object (name of field, boolean value for “changed” status) that includes the fields that have changed only.
const useBookUpdater = (useFormApi, onChange) => {
const bookChanges: Partial<IBook> = useFormApi.watch()
const dirtyFields = useFormApi.formState.dirtyFields
useDeepCompareEffect(() => {
if (!isRecordEmpty(bookChanges)) {
const book = createBookFromDirtyFields(dirtyFields, bookChanges)
onChange(book)
}
}, [bookChanges])
}
And that’s what it takes to add redux
as a caching layer for react-hook-form
.
Usage of the custom Form hook in React
The usage of the custom useBookForm
hook is simple and follows the useForm
api. Since it simply expose the entire form’s api, we can use any of the exported functions of useForm
and don’t have to worry about updating the store for each field.
import { InputField, Sentences } from "@readm/components"
export function Editor({ book }) {
const { onSubmitHandler, useFormApi } = useBookForm(book)
return (
<form onSubmit={onSubmitHandler}>
<InputField control={useFormApi.control} name="title" />
<Sentences api={useFormApi} name="sentences" />
</form>
)
}
This is just a way to achieve that and a solution I have came up with to solve that form hook and redux integration challenge.
Thanks for reading.
Recommend
-
10
JavaScript
-
11
How to Create and Handle NextJS form with React Hook FormDecember 27, 2020Creating a form from scratch without any libraries was easy in React. But, handling the logic was extremely difficult when you start validating dire...
-
9
How to Validate the Form Fields?It’s relatively easier to handle form validation in React Hook Form using the register hook. It also supports basic validation attributes such as req...
-
10
Building forms with validation is tedious and repetitive. So my friend and I created a library of form input components so we can just copy the code in every code base, styled minimally with all error validation message using Tailwind CSS and...
-
7
Building reusable forms can be sometimes challenging. In this tutorial, I will demonstrate how we can build reusable form components with the implementation of react useForHook. We will use next.js boilerplate for this example.
-
5
React Hook Form: An Overview of the Basics + More In this blog, we will explore React Hook Form, an extremely lightweight and effective form building library using React. This open-source, third-part...
-
15
BackReact Form Validation with the useForm HookFebruary 24th, 2022 · 7 min read
-
12
-
19
-
14
File Upload with Chakra UI and react-hook-form · GitHub Instantly share code, notes, and sn...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK