-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
177 additions
and
177 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
--- | ||
title: setValue | ||
description: Update field value | ||
sidebar: apiLinks | ||
--- | ||
|
||
## \</> `setValue:` <TypeText>(name: string, value: unknown, config?: SetValueConfig) => void</TypeText> | ||
|
||
This function allows you to dynamically set the value of a <strong>registered</strong> field and have the options to validate and update the form state. At the same time, it tries to avoid unnecessary rerender. | ||
|
||
### Props | ||
|
||
--- | ||
|
||
| Name | | Description | | ||
| ---------------------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| `name`<br/><TypeText>string</TypeText> | | Target a single field or field array by name. | | ||
| `value`<br/><TypeText>unknown</TypeText> | | The value for the field. This argument is required and can not be `undefined`. | | ||
| `options` | `shouldValidate`<br/><TypeText>boolean</TypeText> | <ul><li>Whether to compute if your input is valid or not (subscribed to <TypeText>errors</TypeText>).</li><li>Whether to compute if your entire form is valid or not (subscribed to <TypeText>isValid</TypeText>).</li>This option will update `touchedFields` at the specified field level not the entire form touched fields.</ul> | | ||
| | `shouldDirty`<br/><TypeText>boolean</TypeText> | <ul><li>Whether to compute if your input is dirty or not against your `defaultValues` (subscribed to <TypeText>dirtyFields</TypeText>).</li><li>Whether to compute if your entire form is dirty or not against your `defaultValues` (subscribed to <TypeText>isDirty</TypeText>).</li><li>This option will update `dirtyFields` at the specified field level not the entire form dirty fields.</li></ul> | | ||
| | `shouldTouch`<br/><TypeText>boolean</TypeText> | Whether to set the input itself to be touched. | | ||
|
||
<Admonition type="important" title="Rules"> | ||
|
||
- You can use methods such as [replace](/docs/usefieldarray#replace) or [update](/docs/usefieldarray#update) for field array, however, they will cause the component to unmount and remount for the targeted field array. | ||
|
||
```javascript | ||
const { update } = useFieldArray({ name: "array" }) | ||
|
||
// unmount fields and remount with updated value | ||
update(0, { test: "1", test1: "2" }) | ||
|
||
// will directly update input value | ||
setValue("array.0.test1", "1") | ||
setValue("array.0.test2", "2") | ||
``` | ||
|
||
- The method will not create a new field when targeting a non-existing field. | ||
|
||
```javascript | ||
const { replace } = useFieldArray({ name: "test" }) | ||
|
||
// ❌ doesn't create new input | ||
setValue("test.101.data") | ||
|
||
// ✅ work on refresh entire field array | ||
replace([{ data: "test" }]) | ||
``` | ||
|
||
- Only the following conditions will trigger a re-render: | ||
|
||
- When an error is triggered or corrected by a value update. | ||
- When `setValue` cause state update, such as dirty and touched. | ||
|
||
- It's recommended to target the field's name rather than make the second argument a nested object. | ||
|
||
```javascript | ||
setValue("yourDetails.firstName", "value") // ✅ performant | ||
setValue("yourDetails", { firstName: "value" }) ❌ // less performant | ||
|
||
register("nestedValue", { value: { test: "data" } }) // register a nested value input | ||
setValue("nestedValue.test", "updatedData") // ❌ failed to find the relevant field | ||
setValue("nestedValue", { test: "updatedData" }) // ✅ setValue find input and update | ||
``` | ||
|
||
- It's recommended to register the input's name before invoking `setValue`. To update the entire `FieldArray`, make sure the `useFieldArray` hook is being executed first. | ||
|
||
**Important:** use `replace` from `useFieldArray` instead, update entire field array with `setValue` will be removed in the next major version. | ||
|
||
```javascript | ||
// you can update an entire Field Array, | ||
setValue("fieldArray", [{ test: "1" }, { test: "2" }]) // ✅ | ||
|
||
// you can setValue to a unregistered input | ||
setValue("notRegisteredInput", "value") // ✅ prefer to be registered | ||
|
||
// the following will register a single input (without register invoked) | ||
setValue("resultSingleNestedField", { test: "1", test2: "2" }) // 🤔 | ||
|
||
// with registered inputs, the setValue will update both inputs correctly. | ||
register("notRegisteredInput.test", "1") | ||
register("notRegisteredInput.test2", "2") | ||
setValue("notRegisteredInput", { test: "1", test2: "2" }) // ✅ sugar syntax to setValue twice | ||
``` | ||
|
||
</Admonition> | ||
|
||
### Examples | ||
|
||
--- | ||
|
||
**Basic** | ||
|
||
```javascript sandbox="https://codesandbox.io/s/react-hook-form-v7-ts-setvalue-8z9hx" | ||
import { useForm } from "react-hook-form" | ||
|
||
const App = () => { | ||
const { register, setValue } = useForm({ | ||
firstName: "", | ||
}) | ||
|
||
return ( | ||
<form> | ||
<input {...register("firstName", { required: true })} /> | ||
<button onClick={() => setValue("firstName", "Bill")}>setValue</button> | ||
<button | ||
onClick={() => | ||
setValue("firstName", "Luo", { | ||
shouldValidate: true, | ||
shouldDirty: true, | ||
}) | ||
} | ||
> | ||
setValue options | ||
</button> | ||
</form> | ||
) | ||
} | ||
``` | ||
|
||
**Dependant Fields** | ||
|
||
```typescript sandbox="https://codesandbox.io/s/dependant-field-dwin1" | ||
import * as React from "react"; | ||
import { useForm } from "react-hook-form"; | ||
|
||
type FormValues = { | ||
a: string; | ||
b: string; | ||
c: string; | ||
}; | ||
|
||
export default function App() { | ||
const { watch, register, handleSubmit, setValue, formState } = useForm< | ||
FormValues | ||
>({ | ||
defaultValues: { | ||
a: "", | ||
b: "", | ||
c: "" | ||
} | ||
}); | ||
const onSubmit = (data: FormValues) => console.log(data); | ||
const [a, b] = watch(["a", "b"]); | ||
|
||
React.useEffect(() => { | ||
if (formState.touchedFields.a && formState.touchedFields.b && a && b) { | ||
setValue("c", `${a} ${b}`); | ||
} | ||
}, [setValue, a, b, formState]); | ||
|
||
return ( | ||
<form onSubmit={handleSubmit(onSubmit)}> | ||
<input {...register("a")} placeholder="a" /> | ||
<input {...register("b")} placeholder="b" /> | ||
<input {...register("c")} placeholder="c" /> | ||
<input type="submit" /> | ||
|
||
<button | ||
type="button" | ||
onClick={() => { | ||
setValue("a", "what", { shouldTouch: true }); | ||
setValue("b", "ever", { shouldTouch: true }); | ||
}} | ||
> | ||
trigger value | ||
</button> | ||
</form> | ||
); | ||
} | ||
``` | ||
|
||
### Video | ||
|
||
--- | ||
|
||
<YouTube youTubeId="qpv51sCH3fI" /> |
This file was deleted.
Oops, something went wrong.