Skip to content

Commit 1170dfc

Browse files
committed
Updated README.md
1 parent 545d38a commit 1170dfc

File tree

1 file changed

+91
-35
lines changed

1 file changed

+91
-35
lines changed

README.md

+91-35
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ npm install --save-prod roqueform
2424
- [Reacting to changes](#reacting-to-changes)
2525
- [Plugins](#plugins)
2626
- [Composing plugins](#composing-plugins)
27+
- [Form submission](#form-submission)
2728
- [Validation](#validation)
2829
- [Accessors](#accessors)
2930

@@ -114,12 +115,14 @@ the `dispatchValue` method that updates the field value:
114115
```ts
115116
const field = useField({ foo: 'bar' });
116117

117-
field.value // → { foo: 'bar' }
118+
field.getValue();
119+
// → { foo: 'bar' }
118120

119121
field.dispatchValue({ foo: 'qux' });
120122

121123
// The field value was updated
122-
field.value // → { foo: 'qux' }
124+
field.getValue();
125+
// → { foo: 'qux' }
123126
```
124127

125128
`useField` doesn't trigger a re-render of the enclosing component. Navigate to
@@ -131,15 +134,21 @@ When the parent field is updated using `dispatchValue`, all of the affected deri
131134
const field = useField({ foo: 'bar' });
132135
const fooField = field.at('foo');
133136

134-
field.value // → { foo: 'bar' }
135-
fooField.value // → 'bar'
137+
field.getValue();
138+
// → { foo: 'bar' }
139+
140+
fooField.getValue();
141+
// → 'bar'
136142

137143
// Updating the root field
138144
field.dispatchValue({ foo: 'qux' });
139145

140146
// The update was propagated to the derived field
141-
field.value // → { foo: 'qux' }
142-
fooField.value // → 'qux'
147+
field.getValue();
148+
// → { foo: 'qux' }
149+
150+
fooField.getValue();
151+
// → 'qux'
143152
```
144153

145154
The same is valid for updating derived fields: when the derived field is updated using `dispatchValue`, the update is
@@ -153,8 +162,11 @@ const fooField = field.at('foo');
153162
fooField.dispatchValue('qux');
154163

155164
// The update was propagated to the parent field
156-
field.value // → { foo: 'qux' }
157-
fooField.value // → 'qux'
165+
field.getValue();
166+
// → { foo: 'qux' }
167+
168+
fooField.getValue();
169+
// → 'qux'
158170
```
159171

160172
`dispatchValue` has a callback signature:
@@ -179,33 +191,41 @@ const fooField = field.at('foo');
179191
fooField.setValue('qux');
180192

181193
// 🟡 Notice that fooField was updated but field wasn't
182-
field.value // → { foo: 'bar' }
183-
fooField.value // → 'qux'
194+
field.getValue();
195+
// → { foo: 'bar' }
196+
197+
fooField.getValue();
198+
// → 'qux'
184199

185200
// Notify the parent, "git commit"
186201
fooField.dispatch();
187202

188203
// Now both fields are in sync
189-
field.value // → { foo: 'qux' }
190-
fooField.value // → 'qux'
204+
field.getValue();
205+
// → { foo: 'qux' }
206+
207+
fooField.getValue();
208+
// → 'qux'
191209
```
192210

193211
`setValue` can be called multiple times, but the most recent update would be propagated to the parent only after
194212
`dispatch`/`dispatchValue` call.
195213

196-
You can check that the field has a transient value using `transient` property:
214+
You can check that the field has a transient value using `isTransient` method:
197215

198216
```ts
199217
const field = useField({ foo: 'bar' });
200218
const fooField = field.at('foo');
201219

202220
fooField.setValue('qux');
203221

204-
fooField.transient // → true
222+
fooField.isTransient();
223+
// → true
205224

206225
fooField.dispatch();
207226

208-
fooField.transient // → false
227+
fooField.isTransient();
228+
// → false
209229
```
210230

211231
## Field observability
@@ -241,7 +261,7 @@ const App = () => {
241261
<Field field={rootField}>
242262
{rootField => (
243263
<input
244-
value={rootField.value}
264+
value={rootField.getValue()}
245265
onChange={event => {
246266
rootField.dispatchValue(event.target.value);
247267
}}
@@ -267,7 +287,7 @@ const App = () => {
267287
{fooField => (
268288
<input
269289
type="text"
270-
value={fooField.value}
290+
value={fooField.getValue()}
271291
onChange={event => {
272292
fooField.dispatchValue(event.target.value);
273293
}}
@@ -279,7 +299,7 @@ const App = () => {
279299
{barField => (
280300
<input
281301
type="number"
282-
value={barField.value}
302+
value={barField.getValue()}
283303
onChange={event => {
284304
barField.dispatchValue(event.target.valueAsNumber);
285305
}}
@@ -311,14 +331,14 @@ const App = () => {
311331

312332
return <>
313333
<Field field={rootField}>
314-
{rootField => JSON.stringify(rootField.value)}
334+
{rootField => JSON.stringify(rootField.getValue())}
315335
</Field>
316336

317337
<Field field={rootField.at('bar')}>
318338
{barField => (
319339
<input
320340
type="text"
321-
value={barField.value}
341+
value={barField.getValue()}
322342
onChange={event => {
323343
barField.dispatchValue(event.target.value);
324344
}}
@@ -339,7 +359,7 @@ affected.
339359
+ field={rootField}
340360
+ eagerlyUpdated={true}
341361
+ >
342-
{rootField => JSON.stringify(rootField.value)}
362+
{rootField => JSON.stringify(rootField.getValue())}
343363
</Field>
344364
```
345365

@@ -360,7 +380,7 @@ is triggered only when the field value was updated [non-transiently](#transient-
360380
{barField => (
361381
<input
362382
type="text"
363-
value={barField.value}
383+
value={barField.getValue()}
364384
onChange={event => {
365385
barField.dispatchValue(event.target.value);
366386
}}
@@ -377,13 +397,13 @@ Let's enhance the field with the `ref` property that would hold the `RefObject`:
377397

378398
```ts
379399
import { createRef } from 'react';
380-
import { useField } from 'roqueform';
400+
import { Plugin, useField } from 'roqueform';
381401

382-
const rootField = useField(
383-
{ bar: 'qux' },
402+
const refPlugin: Plugin<any, { ref: RefObject<HTMLInputElement> }> = field => {
403+
return { ...field, ref: createRef() };
404+
};
384405

385-
field => Object.assign(field, { ref: createRef<HTMLInputElement>() })
386-
);
406+
const rootField = useField({ bar: 'qux' }, refPlugin);
387407
// → Field<{ bar: string }, { ref: RefObject<HTMLInputElement> }> & { ref: RefObject<HTMLInputElement> }
388408
```
389409

@@ -397,7 +417,7 @@ itself.
397417
<input
398418
// 🟡 Notice the ref property
399419
ref={barField.ref}
400-
value={barField.value}
420+
value={barField.getValue()}
401421
onChange={event => {
402422
barField.dispatchValue(event.target.value);
403423
}}
@@ -434,6 +454,42 @@ import { refPlugin } from '@roqueform/ref-plugin';
434454
const field = useField({ bar: 'qux' }, applyPlugins(refPlugin(), anotherPlugin));
435455
```
436456

457+
# Form submission
458+
459+
Without plugins, Roqueform only manages the state of the form fields, and doesn't affect how the form is submitted. So
460+
you can use `form` tags as you did before, but read input values from the `Field` object:
461+
462+
```tsx
463+
const field = useField({ foo: 'bar' });
464+
465+
const handleSubmit = (event: SyntheticEvent): void => {
466+
event.preventDefault();
467+
468+
const value = field.getValue();
469+
// Submit the value here
470+
};
471+
472+
<form onSubmit={handleSubmit}>
473+
<Field field={field.at('bar')}>
474+
{barField => (
475+
<input
476+
name="bar"
477+
value={barField.getValue()}
478+
onChange={event => {
479+
barField.dispatchValue(event.target.value);
480+
}}
481+
/>
482+
)}
483+
</Field>
484+
485+
<button type="submit">
486+
{'Submit'}
487+
</button>
488+
</form>
489+
```
490+
491+
You can always [create a plugin](#plugins) that would enhance the `Field` with custom submit mechanics.
492+
437493
# Validation
438494

439495
Roqueform isn't tied to any validation library. You can use an existing plugin, or write your own plugin to extend
@@ -461,8 +517,8 @@ Plugin enhances all fields with `validate` method that triggers the validation:
461517
```ts
462518
field.validate();
463519

464-
field.at('bar').error?.message
465-
//"Must have the minimum length of 5"
520+
field.at('bar').getError()?.message
521+
//'Must have the minimum length of 5'
466522
```
467523

468524
You can manually set and clear field errors:
@@ -477,10 +533,10 @@ This comes in handy when you receive an error after a backend validation and wan
477533
field.
478534

479535
```tsx
480-
const handleSubmit = (event) => {
536+
const handleSubmit = (event: SyntheticEvent) => {
481537
field.validate();
482538

483-
if (field.invalid) {
539+
if (field.isInvalid()) {
484540
event.preventDefault();
485541
}
486542
};
@@ -491,14 +547,14 @@ const handleSubmit = (event) => {
491547
<>
492548
<input
493549
name="bar"
494-
value={barField.value}
550+
value={barField.getValue()}
495551
onChange={event => {
496552
barField.dispatchValue(event.target.value);
497553
}}
498-
aria-invalid={barField.invalid}
554+
aria-invalid={barField.isInvalid()}
499555
/>
500556

501-
{barField.error?.message}
557+
{barField.getError()?.message}
502558
</>
503559
)}
504560
</Field>

0 commit comments

Comments
 (0)