react-simple-formkit 1.3.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +234 -252
- package/dist/react-simple-formkit.js +4 -4
- package/dist/react-simple-formkit.mjs +439 -326
- package/dist/react-simple-formkit.umd.js +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
# React Simple FormKit
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
-
|
|
3
|
+
Support manage forms as uncontrolled. State updates only when watched. Simple and quick to configure with outstanding efficiency.
|
|
4
|
+
|
|
5
|
+
# Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Peer dependencies](#peer-dependencies)
|
|
8
|
+
- [Features](#features)
|
|
9
|
+
- [Quick start](#quick-start)
|
|
10
|
+
- [Core concepts](#core-concepts)
|
|
11
|
+
- [Modes of input field](#modes-of-input-field)
|
|
12
|
+
- [Watching for updates](#watching-for-updates)
|
|
13
|
+
- [Manage values](#manage-values)
|
|
14
|
+
- [Get value](#get-value)
|
|
15
|
+
- [Set value](#set-value)
|
|
16
|
+
- [Default values and reset](#default-values-and-reset)
|
|
17
|
+
- [Manage states](#manage-states)
|
|
18
|
+
- [Get field states](#get-field-states)
|
|
19
|
+
- [Set field states](#set-field-states)
|
|
20
|
+
- [Manage errors](#manage-errors)
|
|
21
|
+
- [Get field error](#get-field-error)
|
|
22
|
+
- [Set field error](#set-field-error)
|
|
23
|
+
- [APIs](#apis)
|
|
24
|
+
- [useForm](#useForm)
|
|
25
|
+
- [Form](#form)
|
|
26
|
+
- [Controller](#controller)
|
|
27
|
+
- [useController](#useController)
|
|
28
|
+
- [useWatch](#useWatch)
|
|
29
|
+
- [Examples](#examples)
|
|
30
|
+
- [Contact](#contact)
|
|
8
31
|
|
|
9
32
|
# Peer dependencies
|
|
10
33
|
|
|
@@ -15,161 +38,166 @@ Configuration is simple, fast, and efficient. There are also many other tools av
|
|
|
15
38
|
},
|
|
16
39
|
```
|
|
17
40
|
|
|
41
|
+
# Features
|
|
42
|
+
|
|
43
|
+
- [Manage values](#manage-values) (get value, set value, default values, reset values,...)
|
|
44
|
+
- [Manage states](#manage-states) (field dirty, field touched, custom states...)
|
|
45
|
+
- [Manage errors](#manage-errors) (form error, field error...)
|
|
46
|
+
|
|
18
47
|
# Quick start
|
|
19
48
|
|
|
20
49
|
```
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const form = useForm();
|
|
50
|
+
const { control } = useForm();
|
|
24
51
|
|
|
25
52
|
const handleSubmit = (data) => {
|
|
26
53
|
alert(JSON.stringify(data));
|
|
27
54
|
};
|
|
28
55
|
|
|
29
56
|
return (
|
|
30
|
-
<Form
|
|
57
|
+
<Form control={control} onSubmit={handleSubmit} onChange={console.log}>
|
|
58
|
+
<button type="submit">Submit</button>
|
|
31
59
|
<input required name="email" placeholder="email" />
|
|
32
60
|
<input required name="password" type="password" placeholder="password" />
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<input required name="input100" placeholder="input 100" />
|
|
37
|
-
<button type="submit">Submit</button>
|
|
61
|
+
{Array.from({ length: 10 }).map((_, index) => (
|
|
62
|
+
<input name={`input${index + 1}`} placeholder={`input ${index + 1}`} />
|
|
63
|
+
))}
|
|
38
64
|
</Form>
|
|
39
65
|
);
|
|
40
66
|
```
|
|
41
67
|
|
|
42
|
-
#
|
|
68
|
+
# Core concepts
|
|
43
69
|
|
|
44
|
-
##
|
|
70
|
+
## Modes of input field
|
|
45
71
|
|
|
46
|
-
-
|
|
72
|
+
- `Uncontrolled`: Basic input types are supported by the browser and no need to control value
|
|
73
|
+
- `Controlled`: Advanced input types (multiple select, date picker,...) that **require controlled value** or just need to control value
|
|
74
|
+
- `Captured`: Advanced input types **but no need to control value**. Capture only because the browser doesn't support it
|
|
47
75
|
|
|
48
76
|
```
|
|
49
|
-
const
|
|
77
|
+
const { control, actions } = useForm();
|
|
50
78
|
|
|
51
79
|
return (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
)
|
|
80
|
+
<Form control={control} onChange={console.log}>
|
|
81
|
+
{/* Uncontrolled */}
|
|
82
|
+
<input name="number1" placeholder="Enter a number" />
|
|
83
|
+
{/* Controlled by Controller. And the value at this field can be controlled by actions.setValue() */}
|
|
84
|
+
<Controller
|
|
85
|
+
name="multipleSelect"
|
|
86
|
+
render={({ value = "", onChange, name }) => {
|
|
87
|
+
return (
|
|
88
|
+
<Select
|
|
89
|
+
multiple
|
|
90
|
+
name={name}
|
|
91
|
+
value={value.split(",")}
|
|
92
|
+
onChange={(e) => {
|
|
93
|
+
const value = e.target.value;
|
|
94
|
+
// value as array by default but on autofill value as string
|
|
95
|
+
onChange(typeof value === "string" ? value : value.join(","));
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
<MenuItem value="10">Ten</MenuItem>
|
|
99
|
+
<MenuItem value="20">Twenty</MenuItem>
|
|
100
|
+
<MenuItem value="30">Thirty</MenuItem>
|
|
101
|
+
</Select>
|
|
102
|
+
);
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
{/* Captured: This datepicker component changes value immediately with a click with custom onChange */}
|
|
106
|
+
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
107
|
+
<DatePicker name="date" onChange={(newValue) => actions.setValue("date", newValue.format("MM/DD/YYYY"))} />
|
|
108
|
+
</LocalizationProvider>
|
|
109
|
+
<button type="button" onClick={() => alert(JSON.stringify(actions.getValues()))}>
|
|
110
|
+
Get value
|
|
111
|
+
</button>
|
|
112
|
+
<button type="submit">Submit</button>
|
|
113
|
+
</Form>
|
|
114
|
+
)
|
|
59
115
|
```
|
|
60
116
|
|
|
61
|
-
|
|
117
|
+
- **Noticed:** <span style="color:red">_All fields in the form must follow one of the three modes above to ensure the form works correctly_</span>
|
|
62
118
|
|
|
63
|
-
|
|
64
|
-
const form = useForm();
|
|
65
|
-
const { isDirty, isError, errors, actions } = form;
|
|
119
|
+
## Watching for updates
|
|
66
120
|
|
|
67
|
-
|
|
68
|
-
<Form form={form}>
|
|
69
|
-
<input required name="email" placeholder="email" type="email" onBlur={actions.checkValidity} />
|
|
70
|
-
{errors.email && <span>{errors.email}</span>}
|
|
71
|
-
|
|
72
|
-
<button type="submit" disabled={!isDirty || isError}>
|
|
73
|
-
Submit
|
|
74
|
-
</button>
|
|
75
|
-
</Form>
|
|
76
|
-
);
|
|
77
|
-
```
|
|
121
|
+
State updates only when observed via `watch()` or `useWatch()`, or by tracking changes through the Form component's `onChange` callback.
|
|
78
122
|
|
|
79
|
-
|
|
123
|
+
`watch()` will trigger a re-render at the form level.
|
|
124
|
+
`useWatch()` will trigger a re-render only in the component where it is called.
|
|
125
|
+
`onChange` is just a handler callback that is called when field values change.
|
|
80
126
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
127
|
+
# Manage values
|
|
128
|
+
|
|
129
|
+
## Get value
|
|
84
130
|
|
|
85
|
-
return (
|
|
86
|
-
<Form form={form}>
|
|
87
|
-
<input
|
|
88
|
-
required
|
|
89
|
-
name="number"
|
|
90
|
-
onBlur={(e) => {
|
|
91
|
-
let error = null;
|
|
92
|
-
error = actions.getFieldValidity(e);
|
|
93
|
-
|
|
94
|
-
if (error) {
|
|
95
|
-
actions.changeError("number", error);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const value = Number(e.target.value || 0);
|
|
100
|
-
if (value >= 10) error = "Number must be less than 10";
|
|
101
|
-
actions.changeError("number", error);
|
|
102
|
-
}}
|
|
103
|
-
/>
|
|
104
|
-
{errors.number && <span className="error-message">{errors.number}</span>}
|
|
105
|
-
|
|
106
|
-
<button type="submit" disabled={!isDirty || isError}>
|
|
107
|
-
Submit
|
|
108
|
-
</button>
|
|
109
|
-
</Form>
|
|
110
|
-
);
|
|
111
131
|
```
|
|
132
|
+
// watch
|
|
133
|
+
const fieldName = watch("fieldName")
|
|
134
|
+
const fieldName2 = watch("fieldName2")
|
|
135
|
+
// Or
|
|
136
|
+
const { fieldName2, fieldName } = watch(["fieldName", "fieldName2"])
|
|
137
|
+
// Or
|
|
138
|
+
const values = watch("values")
|
|
139
|
+
|
|
140
|
+
// useWatch
|
|
141
|
+
useWatch({ name: "fieldName" })
|
|
142
|
+
useWatch({ name: ["fieldName", "fieldName2"] })
|
|
143
|
+
useWatch({ compute: (values) => values.number > 10 : true : false })
|
|
144
|
+
|
|
145
|
+
// actions.getValues()
|
|
146
|
+
const { actions } = useForm()
|
|
147
|
+
console.log(actions.getValues())
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Set value
|
|
112
151
|
|
|
113
|
-
|
|
152
|
+
actions.setValue() can help to control value of a field. But that field must be controlled by Controller.
|
|
114
153
|
|
|
115
154
|
```
|
|
116
|
-
const
|
|
117
|
-
const
|
|
155
|
+
const { control, actions, watch } = useForm()
|
|
156
|
+
const number = watch("number")
|
|
118
157
|
|
|
119
158
|
return (
|
|
120
|
-
<Form
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
name="number2"
|
|
127
|
-
onBlur={(e) => {
|
|
128
|
-
let error = null;
|
|
129
|
-
error = actions.getFieldValidity(e);
|
|
130
|
-
|
|
131
|
-
if (error) {
|
|
132
|
-
actions.changeError("number2", error);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const value = Number(e.target.value || 0);
|
|
137
|
-
const formState = actions.getFormState();
|
|
138
|
-
const number = Number(formState.number || 0);
|
|
139
|
-
|
|
140
|
-
if (value >= number) error = "Number 2 must be less than number 1";
|
|
141
|
-
actions.changeError("number2", error);
|
|
142
|
-
}}
|
|
159
|
+
<Form control={control} onChange={console.log}>
|
|
160
|
+
<Controller
|
|
161
|
+
name="number"
|
|
162
|
+
render={({ name, value, onChange }) => (
|
|
163
|
+
<input name={name} value={value} onChange={(e) => onChange(e.target.value)} />
|
|
164
|
+
)}
|
|
143
165
|
/>
|
|
144
|
-
|
|
145
|
-
|
|
166
|
+
<button type="button" onClick={() => actions.setValue("number", Number(number || 0) + 1 )}>
|
|
167
|
+
Increase
|
|
168
|
+
</button>
|
|
169
|
+
<button type="submit" disabled={!isDirty}>
|
|
146
170
|
Submit
|
|
147
171
|
</button>
|
|
148
172
|
</Form>
|
|
149
173
|
)
|
|
150
174
|
```
|
|
151
175
|
|
|
152
|
-
##
|
|
176
|
+
## Default values and reset
|
|
153
177
|
|
|
154
178
|
```
|
|
155
|
-
const
|
|
156
|
-
|
|
179
|
+
const dummyFields = Array.from({ length: 10 }).reduce(
|
|
180
|
+
(acc, _, index) => ({ ...acc, [`input${index + 1}`]: `input${index + 1}` }),
|
|
181
|
+
{}
|
|
182
|
+
);
|
|
157
183
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
184
|
+
const { control, watch, actions } = useForm({ defaultValues: dummyFields });
|
|
185
|
+
|
|
186
|
+
const handleSubmit = async (newValues) => {
|
|
187
|
+
// update to server
|
|
188
|
+
await new Promise(res => setTimeout(res, 1000))
|
|
189
|
+
// reset with new defaultValues
|
|
190
|
+
actions.reset(newValues)
|
|
191
|
+
}
|
|
162
192
|
|
|
163
193
|
return (
|
|
164
|
-
<Form
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
)}
|
|
172
|
-
/>
|
|
194
|
+
<Form control={control} onSubmit={handleSubmit} onChange={console.log}>
|
|
195
|
+
{Object.keys(dummyFields).map((name) => (
|
|
196
|
+
<input name={name} placeholder={name} />
|
|
197
|
+
))}
|
|
198
|
+
<button type="reset" disabled={!isDirty}>
|
|
199
|
+
Reset
|
|
200
|
+
</button>
|
|
173
201
|
<button type="submit" disabled={!isDirty}>
|
|
174
202
|
Submit
|
|
175
203
|
</button>
|
|
@@ -177,79 +205,50 @@ return (
|
|
|
177
205
|
);
|
|
178
206
|
```
|
|
179
207
|
|
|
180
|
-
|
|
208
|
+
# Manage states
|
|
181
209
|
|
|
182
|
-
|
|
183
|
-
- You can also use actions.getDefaultValues() to check what is stored
|
|
210
|
+
## Get field states
|
|
184
211
|
|
|
185
212
|
```
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
setLoading(true);
|
|
194
|
-
await new Promise((res) => setTimeout(res, 1500));
|
|
195
|
-
setDefaultValues(data);
|
|
196
|
-
// After update default values, reload the form
|
|
197
|
-
// Because data updating is asynchronous. Catching it's change is ineffective.
|
|
198
|
-
actions.reload();
|
|
199
|
-
setLoading(false);
|
|
200
|
-
};
|
|
213
|
+
// watch() or useWatch()
|
|
214
|
+
const isFormDirty = watch("isDirty")
|
|
215
|
+
const { fieldName: {...}, fieldName2: {...} } = watch("fieldStates")
|
|
216
|
+
const { isDirty, isTouched } = watch("fieldStates.fieldName")
|
|
217
|
+
const isFieldDirty = watch("fieldStates.fieldName.isDirty")
|
|
218
|
+
const fieldCustomState = watch("fieldStates.fieldName.customState")
|
|
219
|
+
```
|
|
201
220
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
render={({ ref, name, defaultValue, value, setValue }) => (
|
|
208
|
-
<input
|
|
209
|
-
ref={ref}
|
|
210
|
-
required
|
|
211
|
-
name={name}
|
|
212
|
-
type="password"
|
|
213
|
-
defaultValue={defaultValue}
|
|
214
|
-
value={value}
|
|
215
|
-
onChange={(e) => setValue(e.target.value)}
|
|
216
|
-
/>
|
|
217
|
-
)}
|
|
218
|
-
/>
|
|
219
|
-
<button type="reset" disabled={!isDirty}>
|
|
220
|
-
Reset
|
|
221
|
-
</button>
|
|
222
|
-
<Button disableElevation variant="contained" type="submit" loading={loading} disabled={!isDirty}>
|
|
223
|
-
Submit
|
|
224
|
-
</Button>
|
|
225
|
-
</Form>
|
|
226
|
-
);
|
|
221
|
+
## Set field states
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
actions.setFieldStateProperty('fieldName', 'customState', { hello: "world" })
|
|
225
|
+
// This will trigger re-render at watch(), useWatch() and render function in Controller
|
|
227
226
|
```
|
|
228
227
|
|
|
229
|
-
#
|
|
228
|
+
# Manage errors
|
|
230
229
|
|
|
231
|
-
##
|
|
230
|
+
## Get field error
|
|
232
231
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
232
|
+
```
|
|
233
|
+
// watch() or useWatch()
|
|
234
|
+
const isFormError = watch("isError")
|
|
235
|
+
const fieldError = watch("errors.fieldName")
|
|
236
|
+
const { fieldName, fieldName2 } = watch("errors")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Set field error
|
|
236
240
|
|
|
237
241
|
```
|
|
238
|
-
|
|
239
|
-
const {
|
|
242
|
+
// actions.setError()
|
|
243
|
+
const { control, actions, watch } = useForm()
|
|
244
|
+
const { isError, ["errors.input1"]: input1Error } = watch(["isError", "errors.input1"])
|
|
240
245
|
|
|
241
246
|
return (
|
|
242
|
-
<Form
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
</Select>
|
|
248
|
-
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
|
249
|
-
<DatePicker name="date" onChange={actions.instantChange} />
|
|
250
|
-
</LocalizationProvider>
|
|
251
|
-
<button type="button" onClick={() => alert(JSON.stringify(actions.getFormState()))}>
|
|
252
|
-
Get value
|
|
247
|
+
<Form control={control} onChange={console.log}>
|
|
248
|
+
<input name="input1" />
|
|
249
|
+
{errors.input1 && <span className="error-message">{input1Error}</span>}
|
|
250
|
+
<button type="button" onClick={() => actions.setError("number", "This is error message")}>
|
|
251
|
+
Set Error
|
|
253
252
|
</button>
|
|
254
253
|
<button type="submit" disabled={!isDirty}>
|
|
255
254
|
Submit
|
|
@@ -258,87 +257,70 @@ return (
|
|
|
258
257
|
)
|
|
259
258
|
```
|
|
260
259
|
|
|
261
|
-
|
|
260
|
+
# APIs
|
|
262
261
|
|
|
263
|
-
|
|
264
|
-
- Make field assignable by actions.setValue
|
|
262
|
+
## useForm
|
|
265
263
|
|
|
266
|
-
|
|
267
|
-
import { Controller, Form, useForm } from "react-simple-formkit";
|
|
264
|
+
Generic props:
|
|
268
265
|
|
|
269
|
-
|
|
270
|
-
|
|
266
|
+
- `defaultValues`: `Object` [Example](#default-values-and-reset)
|
|
267
|
+
- `shouldUnRegister`: `Boolean` Default is **false**,
|
|
268
|
+
- `shouldConvertNumber`: `Boolean` Default is **false**
|
|
269
|
+
- `numberFields`: `Array` if passed, shouldConvertNumber will set **true**. Lib auto load field with type **number** by default
|
|
271
270
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
ref={ref}
|
|
325
|
-
value={value}
|
|
326
|
-
onChange={(e) => setValue(e.target.value)}
|
|
327
|
-
name={name}
|
|
328
|
-
placeholder="sum(number1, number2)"
|
|
329
|
-
/>
|
|
330
|
-
)}
|
|
331
|
-
/>
|
|
332
|
-
<button type="button" onClick={() => alert(JSON.stringify(actions.getFormState()))}>
|
|
333
|
-
Get value
|
|
334
|
-
</button>
|
|
335
|
-
<button type="submit" disabled={!isDirty}>
|
|
336
|
-
Submit
|
|
337
|
-
</button>
|
|
338
|
-
</Form>
|
|
339
|
-
)
|
|
340
|
-
```
|
|
271
|
+
Return:
|
|
272
|
+
|
|
273
|
+
- `control`: contains methods and utilities to control the form.
|
|
274
|
+
- `watch(name)`: `Function` [Example](#manage-values)
|
|
275
|
+
- `actions` is an object that contains utilities
|
|
276
|
+
- `actions.reset()`: [Example](#default-values-and-reset)
|
|
277
|
+
- `actions.getValues()`: [Example](#manage-values)
|
|
278
|
+
- `actions.setValue()`: [Example](#set-value)
|
|
279
|
+
- `actions.setError()`: [Example](#set-field-error)
|
|
280
|
+
- `actions.clearError()`
|
|
281
|
+
- `actions.clearErrors()`
|
|
282
|
+
- `actions.getNumberFields()`
|
|
283
|
+
- `actions.getDefaultValues()`
|
|
284
|
+
- `actions.setFieldStateProperty()`: [Example](#set-field-states)
|
|
285
|
+
|
|
286
|
+
## Form
|
|
287
|
+
|
|
288
|
+
Generic props:
|
|
289
|
+
|
|
290
|
+
- `control`: received from useForm()
|
|
291
|
+
- `onSubmit`: `(currentValues) => {}` call when form submit by button type='submit'
|
|
292
|
+
- `onChange`: `(name, value, currentValues) => {}` call when any field changes
|
|
293
|
+
|
|
294
|
+
## Controller
|
|
295
|
+
|
|
296
|
+
Generic props:
|
|
297
|
+
|
|
298
|
+
- `name`
|
|
299
|
+
- `defaultValue`
|
|
300
|
+
- `render({name, value, onChange, customState, setCustomState})`
|
|
301
|
+
|
|
302
|
+
## useController
|
|
303
|
+
|
|
304
|
+
Generic props:
|
|
305
|
+
|
|
306
|
+
- `name`
|
|
307
|
+
- `defaultValue`
|
|
308
|
+
|
|
309
|
+
Return: everything in render function above
|
|
310
|
+
|
|
311
|
+
## useWatch
|
|
312
|
+
|
|
313
|
+
[Example](#manage-values)
|
|
314
|
+
|
|
315
|
+
Generic props:
|
|
316
|
+
|
|
317
|
+
- `name`: `String | Array`
|
|
318
|
+
- compute: `Function` that will calculate from form values and return a value. It will make re-render when the result changes
|
|
319
|
+
|
|
320
|
+
# Examples
|
|
321
|
+
|
|
322
|
+
- https://codesandbox.io/p/sandbox/react-simple-formkit-examples-rhmhjj
|
|
341
323
|
|
|
342
324
|
# Contact
|
|
343
325
|
|
|
344
|
-
For any ideas or issues, please get in touch with me at anhhuy2000@gmail.com
|
|
326
|
+
For any ideas or issues, please get in touch with me at **anhhuy2000@gmail.com**
|