1
-
2
1
# Getting Started With ` react-reactive-form `
3
2
The basic implementation of reactive forms is super easy but it may be helpful to read a brief description of the core form classes.
4
3
* [ Abstract Control] ( api/AbstractControl.md )
@@ -11,9 +10,9 @@ The basic implementation of reactive forms is super easy but it may be helpful t
11
10
### step 1: Create FormGroup or FormArray
12
11
A form group is a collection object of form controls & form array is the collection array of form controls.
13
12
14
- There are two ways to create these:
13
+ There are three ways to create these:
15
14
16
- #### With FormBuilder
15
+ #### With FormBuilder ( Static Controls )
17
16
The FormBuilder class helps reduce repetition and clutter by handling details of control creation for you.
18
17
` FormBuilder.group ` is a static method that creates a FormGroup. ` FormBuilder.group ` takes an object whose keys and values are
19
18
` FormControl ` names and their definitions. In this example, the username control is defined by its initial data value,
@@ -31,7 +30,7 @@ const loginForm = FormBuilder.group({
31
30
});
32
31
```
33
32
34
- #### Without FormBuilder
33
+ #### Without FormBuilder ( Static Controls )
35
34
36
35
``` js
37
36
import { FormGroup , FormControl } from " react-reactive-form" ;
@@ -42,79 +41,103 @@ const loginForm = new FormGroup({
42
41
})
43
42
```
44
43
44
+ #### Without initializing the controls ( Dynamic Controls )
45
+
46
+ You can also create controls without even initializing the group control object with the help of new react form components ( [ FieldGroup] ( api/FieldGroup.md ) , [ FieldControl] ( api/FieldControl.md ) , [ FieldArray] ( api/FieldArray.md ) ).
47
+
48
+ For eg.
49
+
50
+ ``` ts
51
+ < FieldGroup
52
+ render = {({ value }) => (
53
+ <form>
54
+ <FieldControl
55
+ name = " test"
56
+ render = {({ handler }) => <input {... handler ()}/>}
57
+ />
58
+ <pre>{value .toString ()}</pre>
59
+ </form>)}
60
+ / >
61
+ ```
62
+ The above example will create an instance of [ FormGroup] ( FormGroup.md ) class which has a control named ` test ` .
63
+
64
+
45
65
### step2: Connect form with component
46
- [ Field] ( api/Field.md ) component subscribes a particular control & only update it when it’s or it’s parent’s state changes, which improves the performance by restricting the unnecessary re-rendering of other fields.
66
+ This steps is not needed if you're using dynamic controls but if you want a better control over your form state then you should do that, if your controls are dynamic then you can also initalize the empty group control and add the controls later.
67
+ Example:
47
68
48
69
``` js
49
70
import React , { Component } from ' react' ;
50
- import { FormBuilder , Validators , Field } from " react-reactive-form" ;
71
+ import {
72
+ FormBuilder ,
73
+ FieldGroup ,
74
+ FieldControl ,
75
+ Validators ,
76
+ } from " react-reactive-form" ;
51
77
52
78
export default class Login extends Component {
53
- constructor (props ) {
54
- super (props);
55
- // Create the controls
56
- this .loginForm = FormBuilder .group ({
79
+ loginForm = FormBuilder .group ({
57
80
username: [" " , Validators .required ],
58
81
password: [" " , Validators .required ],
59
82
rememberMe: false
60
83
});
61
84
}
62
- handleReset = (e ) => {
85
+ handleReset = () => {
63
86
this .loginForm .reset ();
64
- e .preventDefault ();
65
87
}
66
88
handleSubmit = (e ) => {
67
- console .log (" Form values" , this .loginForm .value );
68
89
e .preventDefault ();
90
+ console .log (" Form values" , this .loginForm .value );
69
91
}
70
92
render () {
71
93
return (
72
- < Field
94
+ < FieldGroup
73
95
control= {this .loginForm }
74
96
render= {({ get, invalid }) => (
75
97
< form onSubmit= {this .handleSubmit }>
76
- < Field
77
- control = { get ( " username" )}
98
+ < FieldControl
99
+ name = " username"
78
100
render= {({ handler, touched, hasError }) => (
79
101
< div>
80
102
< input {... handler ()}/ >
81
103
< span>
82
- {touched
104
+ {touched
83
105
&& hasError (" required" )
84
106
&& " Username is required" }
85
107
< / span>
86
108
< / div>
87
109
)}
88
110
/ >
89
- < Field
90
- control = { get ( " password" )}
111
+ < FieldControl
112
+ name = " password"
91
113
render= {({ handler, touched, hasError }) => (
92
114
< div>
93
115
< input {... handler ()}/ >
94
116
< span>
95
- {touched
117
+ {touched
96
118
&& hasError (" required" )
97
119
&& " Password is required" }
98
120
< / span>
99
121
< / div>
100
122
)}
101
123
/ >
102
- < Field
103
- control = { get ( " rememberMe" )}
124
+ < FieldControl
125
+ name = " rememberMe"
104
126
render= {({handler}) => (
105
127
< div>
106
128
< input {... handler (" checkbox" )}/ >
107
129
< / div>
108
130
)}
109
131
/ >
110
- < button
132
+ < button
133
+ type= " button"
111
134
onClick= {this .handleReset }
112
135
>
113
136
Reset
114
137
< / button>
115
138
< button
116
139
type= " submit"
117
- disabled= {invalid}
140
+ disabled= {invalid}
118
141
>
119
142
Submit
120
143
< / button>
@@ -125,3 +148,84 @@ export default class Login extends Component {
125
148
}
126
149
}
127
150
```
151
+
152
+ ## Common Operations
153
+
154
+ ### Add Listeners
155
+
156
+ You can add subscriptions for listening the state changes in form.
157
+ There are a total of five observables available currently:
158
+
159
+ #### valueChanges
160
+ Emits an event every time when the control's value changes.
161
+ #### stateChanges
162
+ Emits an event every time when the control's state(value, touched, ...) changes.
163
+ #### statusChanges
164
+ Emits an event every time when the control's status(PENDING, INVALID, VALID, DISABLED) changes.
165
+ #### onValueChanges
166
+ Emits an event every time when the control's value is changed by onChange event i.e by user.
167
+ #### onBlurChnages
168
+ Emits an event every time when a blur event triggers on a control.
169
+
170
+ You can use these listeners to modify the form state dynamically based on the value of other controls.
171
+
172
+ Example:
173
+
174
+ #### Disable/Enable a control based on another control's value
175
+
176
+ ``` js
177
+ class Form extends Component {
178
+ myForm = {
179
+ public: true ,
180
+ images: [[]]
181
+ }
182
+ componentDidMount () {
183
+ this .myForm .get (' public' ).valueChanges .subscribe ((value ) => {
184
+ const imagesControl = this .myForm .get (' images' )
185
+ if (value) {
186
+ imagesControl .disable ()
187
+ } else {
188
+ imagesControl .enable ()
189
+ }
190
+ })
191
+ }
192
+ componentWillUnmount () {
193
+ this .myForm .get (' public' ).valueChanges .unsubscribe ()
194
+ }
195
+ }
196
+ ```
197
+
198
+ #### Set the value of a control based on another control's value
199
+
200
+ The following example ensures that one of the control's value must be ` true ` .
201
+
202
+ ``` js
203
+ class Form extends Component {
204
+ myForm = {
205
+ showMeMen: true ,
206
+ showMeWomen: true
207
+ }
208
+ componentDidMount () {
209
+ const showMeMenControl = this .myForm .get (' showMeMen' ).unsubscribe ()
210
+ const showMeWomenControl = this .myForm .get (' showMeWomen' )
211
+
212
+ showMeMenControl .valueChanges .subscribe ((value ) => {
213
+ if (! value && ! showMeWomenControl .value ) {
214
+ showMeWomenControl .setValue (true )
215
+ }
216
+ })
217
+
218
+ showMeWomenControl .valueChanges .subscribe ((value ) => {
219
+ if (! value && ! showMeMenControl .value ) {
220
+ showMeMenControl .setValue (true )
221
+ }
222
+ })
223
+
224
+ }
225
+
226
+ componentWillUnmount () {
227
+ this .myForm .get (' showMeMen' ).valueChanges .unsubscribe ()
228
+ this .myForm .get (' showMeWomen' ).valueChanges .unsubscribe ()
229
+ }
230
+ }
231
+ ```
0 commit comments