@@ -11,7 +11,6 @@ React Hook Form has support for native form validation, which lets you validate
11
11
The following code example works as intended for validation; however, it can be improved for accessibility.
12
12
13
13
``` javascript copy
14
- import React from " react"
15
14
import { useForm } from " react-hook-form"
16
15
17
16
export default function App () {
@@ -190,7 +189,7 @@ Let's have a look what's in each of these components.
190
189
The ` Form ` component's responsibility is to inject all ` react-hook-form ` methods into the child component.
191
190
192
191
``` javascript copy sandbox="https://codesandbox.io/s/react-hook-form-smart-form-component-forked-iq89z"
193
- import React from " react"
192
+ import { Children , createElement } from " react"
194
193
import { useForm } from " react-hook-form"
195
194
196
195
export default function Form ({ defaultValues, children, onSubmit }) {
@@ -199,9 +198,9 @@ export default function Form({ defaultValues, children, onSubmit }) {
199
198
200
199
return (
201
200
< form onSubmit= {handleSubmit (onSubmit)}>
202
- {React . Children .map (children, (child ) => {
201
+ {Children .map (children, (child ) => {
203
202
return child .props .name
204
- ? React . createElement (child .type , {
203
+ ? createElement (child .type , {
205
204
... {
206
205
... child .props ,
207
206
register: methods .register ,
@@ -220,8 +219,6 @@ export default function Form({ defaultValues, children, onSubmit }) {
220
219
Those input components' responsibility is to register them into ` react-hook-form ` .
221
220
222
221
``` javascript copy sandbox="https://codesandbox.io/s/react-hook-form-smart-form-component-forked-iq89z"
223
- import React from " react"
224
-
225
222
export function Input ({ register, name, ... rest }) {
226
223
return < input {... register (name)} {... rest} / >
227
224
}
@@ -277,7 +274,7 @@ import { FormProvider, useForm, useFormContext } from "react-hook-form"
277
274
export const ConnectForm = ({ children }) => {
278
275
const methods = useFormContext ()
279
276
280
- return children ({ ... methods } )
277
+ return children (methods)
281
278
}
282
279
283
280
export const DeepNest = () => (
@@ -308,7 +305,7 @@ React Hook Form's [FormProvider](/docs/formprovider) is built upon [React's Cont
308
305
** Note:** Using React Hook Form's [ Devtools] ( /dev-tools ) alongside [ FormProvider] ( /docs/formprovider ) can cause performance issues in some situations. Before diving deep in performance optimizations, consider this bottleneck first.
309
306
310
307
``` javascript copy sandbox="https://codesandbox.io/s/provider-perf-forked-r24ho"
311
- import React , { memo } from " react"
308
+ import { memo } from " react"
312
309
import { useForm , FormProvider , useFormContext } from " react-hook-form"
313
310
314
311
// we can use React.memo to prevent re-render except isDirty state changed
@@ -354,7 +351,6 @@ React Hook Form embraces uncontrolled components but is also compatible with con
354
351
<TabGroup buttonLabels = { [" Controller" , " Custom Register" ]} >
355
352
356
353
``` javascript copy
357
- import React , { useEffect } from " react"
358
354
import { Input , Select , MenuItem } from " @material-ui/core"
359
355
import { useForm , Controller } from " react-hook-form"
360
356
@@ -364,7 +360,7 @@ const defaultValues = {
364
360
}
365
361
366
362
function App () {
367
- const { handleSubmit , reset , watch , control , register } = useForm ({
363
+ const { handleSubmit , reset , control , register } = useForm ({
368
364
defaultValues,
369
365
})
370
366
const onSubmit = (data ) => console .log (data)
@@ -395,7 +391,7 @@ function App() {
395
391
```
396
392
397
393
``` javascript copy sandbox="https://codesandbox.io/s/react-hook-form-controlled-mixed-with-uncontrolled-forked-c323j"
398
- import React , { useEffect } from " react"
394
+ import { useEffect } from " react"
399
395
import { Input , Select , MenuItem } from " @material-ui/core"
400
396
import { useForm } from " react-hook-form"
401
397
@@ -447,7 +443,7 @@ You can build a custom hook as a resolver. A custom hook can easily integrate wi
447
443
- Pass the validation resolver to the useForm hook
448
444
449
445
``` javascript copy sandbox="https://codesandbox.io/s/custom-hook-with-resolver-v7-cwczk"
450
- import React , { useCallback , useMemo } from " react"
446
+ import { useCallback } from " react"
451
447
import { useForm } from " react-hook-form"
452
448
import * as yup from " yup"
453
449
@@ -512,31 +508,29 @@ An example is shown below using [react-window](https://github.com/bvaughn/react-
512
508
<TabGroup buttonLabels={["Form", "Field Array"]}>
513
509
514
510
` ` ` javascript copy sandbox= " https://codesandbox.io/s/react-hook-form-with-react-window-forked-3j3mq"
515
- import React from " react"
511
+ import { memo } from " react"
516
512
import { FormProvider , useForm , useFormContext } from " react-hook-form"
517
513
import { VariableSizeList as List } from " react-window"
518
514
import AutoSizer from " react-virtualized-auto-sizer"
519
- import ReactDOM from " react-dom"
520
- import " ./styles.css"
521
515
522
516
const items = Array .from (Array (1000 ).keys ()).map ((i ) => ({
523
517
title: ` List ${ i} ` ,
524
518
quantity: Math .floor (Math .random () * 10 ),
525
519
}))
526
520
527
- const WindowedRow = React . memo (({ index, style, data }) => {
521
+ const WindowedRow = memo (({ index, style, data }) => {
528
522
const { register } = useFormContext ()
529
523
530
524
return < input {... register (` ${ index} .quantity` )} / >
531
525
})
532
526
533
527
export const App = () => {
534
528
const onSubmit = (data ) => console .log (data)
535
- const formMethods = useForm ({ defaultValues: items })
529
+ const methods = useForm ({ defaultValues: items })
536
530
537
531
return (
538
- < form className = " form " onSubmit= {formMethods .handleSubmit (onSubmit)}>
539
- < FormProvider {... formMethods }>
532
+ < form onSubmit= {methods .handleSubmit (onSubmit)}>
533
+ < FormProvider {... methods }>
540
534
< AutoSizer>
541
535
{({ height, width }) => (
542
536
< List
@@ -572,7 +566,7 @@ function App() {
572
566
test: items,
573
567
},
574
568
})
575
- const { fields , remove } = useFieldArray ({ control, name: " test" })
569
+ const { fields } = useFieldArray ({ control, name: " test" })
576
570
577
571
return (
578
572
< FixedSizeList
@@ -652,7 +646,6 @@ Additionally, you can set up [eslint-plugin-testing-library](https://github.com/
652
646
We have set the role attribute accordingly. These attributes are helpful for when you write tests, and they improve accessibility. For more information, you can refer to the [testing-library](https://testing-library.com/) documentation.
653
647
654
648
` ` ` javascript copy sandbox= " https://codesandbox.io/s/react-hook-form-unit-test-docs-066zk?file=/src/App.js"
655
- import React from " react"
656
649
import { useForm } from " react-hook-form"
657
650
658
651
export default function App ({ login }) {
@@ -716,7 +709,6 @@ The following criteria are what we try to cover with the tests:
716
709
- Test successful submission.
717
710
718
711
` ` ` javascript copy sandbox= " https://codesandbox.io/s/react-hook-form-unit-test-docs-066zk?file=/src/App.test.js"
719
- import React from " react"
720
712
import { render , screen , fireEvent , waitFor } from " @testing-library/react"
721
713
import App from " ./App"
722
714
@@ -812,11 +804,10 @@ If you test a component that uses react-hook-form, you might run into a warning
812
804
> Warning: An update to MyComponent inside a test was not wrapped in act(...)
813
805
814
806
` ` ` javascript copy sandbox= " https://codesandbox.io/s/react-hook-form-unit-test-act-warning-docs-yq7uj?file=/src/App.js"
815
- import React from " react"
816
807
import { useForm } from " react-hook-form"
817
808
818
809
export default function App () {
819
- const { register , handleSubmit , formState } = useForm ({
810
+ const { register , handleSubmit } = useForm ({
820
811
mode: " onChange" ,
821
812
})
822
813
const onSubmit = (data ) => {}
@@ -835,7 +826,6 @@ export default function App() {
835
826
` ` `
836
827
837
828
` ` ` javascript copy sandbox= " https://codesandbox.io/s/react-hook-form-unit-test-act-warning-docs-yq7uj?file=/src/App.test.js"
838
- import React from " react"
839
829
import { render , screen } from " @testing-library/react"
840
830
import App from " ./App"
841
831
@@ -853,7 +843,6 @@ This is because react-hook-form internally uses asynchronous validation handlers
853
843
To solve this, wait until some element from your UI appears with ` find* ` queries. Note that you **must not** wrap your ` render ()` calls in ` act ()` . [You can read more about wrapping things in ` act` unnecessarily here](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#wrapping-things-in-act-unnecessarily).
854
844
855
845
` ` ` javascript copy sandbox= " https://codesandbox.io/s/react-hook-form-unit-test-act-warning-docs-tcb7y?file=/src/App.test.js"
856
- import React from " react"
857
846
import { render , screen } from " @testing-library/react"
858
847
import App from " ./App"
859
848
@@ -875,13 +864,9 @@ it("should have a submit button", async () => {
875
864
The native input returns the value in ` string` format unless invoked with ` valueAsNumber` or ` valueAsDate` , you can read more under [this section](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement). However, it's not perfect. We still have to deal with ` isNaN` or ` null ` values. So it's better to leave the transform at the custom hook level. In the following example, we are using the ` Controller` to include the functionality of the transform value's input and output. You can also achieve a similar result with a custom ` register` .
876
865
877
866
` ` ` javascript copy sandbox= " https://codesandbox.io/s/transform-vt3tm"
867
+ import { Controller } from " react-hook-form"
878
868
879
- const ControllerPlus = ({
880
- control,
881
- transform,
882
- name,
883
- defaultValue
884
- }) => (
869
+ const ControllerPlus = ({ control, transform, name, defaultValue }) => (
885
870
< Controller
886
871
defaultValue= {defaultValue}
887
872
control= {control}
@@ -893,17 +878,16 @@ const ControllerPlus = ({
893
878
/ >
894
879
)}
895
880
/ >
896
- );
881
+ )
897
882
898
883
// usage below:
899
- < ControllerPlus< string, number >
884
+ < ControllerPlus
900
885
transform= {{
901
- input : (value ) =>
902
- isNaN (value) || value === 0 ? " " : value .toString (),
886
+ input : (value ) => (isNaN (value) || value === 0 ? " " : value .toString ()),
903
887
output : (e ) => {
904
- const output = parseInt (e .target .value , 10 );
905
- return isNaN (output) ? 0 : output;
906
- }
888
+ const output = parseInt (e .target .value , 10 )
889
+ return isNaN (output) ? 0 : output
890
+ },
907
891
}}
908
892
control= {control}
909
893
name= " number"
0 commit comments