1
1
import toChildrenArray from 'rc-util/lib/Children/toArray' ;
2
+ import warning from 'rc-util/lib/warning' ;
2
3
import * as React from 'react' ;
3
4
import {
4
5
FieldEntity ,
@@ -33,7 +34,11 @@ interface ChildProps {
33
34
export interface FieldProps {
34
35
children ?:
35
36
| React . ReactElement
36
- | ( ( control : ChildProps , meta : Meta , form : FormInstance ) => React . ReactNode ) ;
37
+ | ( (
38
+ control : ChildProps ,
39
+ meta : Meta ,
40
+ form : FormInstance ,
41
+ ) => React . ReactNode ) ;
37
42
/**
38
43
* Set up `dependencies` field.
39
44
* When dependencies field update and current field is touched,
@@ -42,11 +47,19 @@ export interface FieldProps {
42
47
dependencies ?: NamePath [ ] ;
43
48
getValueFromEvent ?: ( ...args : EventArgs ) => StoreValue ;
44
49
name ?: NamePath ;
45
- normalize ?: ( value : StoreValue , prevValue : StoreValue , allValues : Store ) => StoreValue ;
50
+ normalize ?: (
51
+ value : StoreValue ,
52
+ prevValue : StoreValue ,
53
+ allValues : Store ,
54
+ ) => StoreValue ;
46
55
rules ?: Rule [ ] ;
47
56
shouldUpdate ?:
48
57
| true
49
- | ( ( prevValues : Store , nextValues : Store , info : { source ?: string } ) => boolean ) ;
58
+ | ( (
59
+ prevValues : Store ,
60
+ nextValues : Store ,
61
+ info : { source ?: string } ,
62
+ ) => boolean ) ;
50
63
trigger ?: string ;
51
64
validateTrigger ?: string | string [ ] | false ;
52
65
valuePropName ?: string ;
@@ -58,7 +71,8 @@ export interface FieldState {
58
71
}
59
72
60
73
// We use Class instead of Hooks here since it will cost much code by using Hooks.
61
- class Field extends React . Component < FieldProps , FieldState > implements FieldEntity {
74
+ class Field extends React . Component < FieldProps , FieldState >
75
+ implements FieldEntity {
62
76
public static contextType = FieldContext ;
63
77
64
78
public static defaultProps = {
@@ -164,10 +178,15 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
164
178
const prevValue = this . getValue ( prevStore ) ;
165
179
const curValue = this . getValue ( ) ;
166
180
167
- const namePathMatch = namePathList && containsNamePath ( namePathList , namePath ) ;
181
+ const namePathMatch =
182
+ namePathList && containsNamePath ( namePathList , namePath ) ;
168
183
169
184
// `setFieldsValue` is a quick access to update related status
170
- if ( info . type === 'valueUpdate' && info . source === 'external' && prevValue !== curValue ) {
185
+ if (
186
+ info . type === 'valueUpdate' &&
187
+ info . source === 'external' &&
188
+ prevValue !== curValue
189
+ ) {
171
190
this . touched = true ;
172
191
this . validatePromise = null ;
173
192
this . errors = [ ] ;
@@ -216,7 +235,9 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
216
235
const dependencyList = dependencies . map ( getNamePath ) ;
217
236
if (
218
237
namePathMatch ||
219
- dependencyList . some ( dependency => containsNamePath ( info . relatedFields , dependency ) )
238
+ dependencyList . some ( dependency =>
239
+ containsNamePath ( info . relatedFields , dependency ) ,
240
+ )
220
241
) {
221
242
this . reRender ( ) ;
222
243
return ;
@@ -237,7 +258,11 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
237
258
containsNamePath ( namePathList , getNamePath ( dependency ) ) ,
238
259
) ||
239
260
( typeof shouldUpdate === 'function'
240
- ? shouldUpdate ( prevStore , values , 'source' in info ? { source : info . source } : { } )
261
+ ? shouldUpdate (
262
+ prevStore ,
263
+ values ,
264
+ 'source' in info ? { source : info . source } : { } ,
265
+ )
241
266
: prevValue !== curValue )
242
267
) {
243
268
this . reRender ( ) ;
@@ -267,7 +292,12 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
267
292
} ) ;
268
293
}
269
294
270
- const promise = validateRules ( namePath , this . getValue ( ) , filteredRules , options ) ;
295
+ const promise = validateRules (
296
+ namePath ,
297
+ this . getValue ( ) ,
298
+ filteredRules ,
299
+ options ,
300
+ ) ;
271
301
this . validatePromise = promise ;
272
302
this . errors = [ ] ;
273
303
@@ -309,22 +339,28 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
309
339
public getOnlyChild = (
310
340
children :
311
341
| React . ReactNode
312
- | ( ( control : ChildProps , meta : Meta , context : FormInstance ) => React . ReactNode ) ,
313
- ) : { child : React . ReactElement | null ; isFunction : boolean } => {
342
+ | ( (
343
+ control : ChildProps ,
344
+ meta : Meta ,
345
+ context : FormInstance ,
346
+ ) => React . ReactNode ) ,
347
+ ) : { child : React . ReactNode | null ; isFunction : boolean } => {
314
348
// Support render props
315
349
if ( typeof children === 'function' ) {
316
350
const meta = this . getMeta ( ) ;
317
351
318
352
return {
319
- ...this . getOnlyChild ( children ( this . getControlled ( ) , meta , this . context ) ) ,
353
+ ...this . getOnlyChild (
354
+ children ( this . getControlled ( ) , meta , this . context ) ,
355
+ ) ,
320
356
isFunction : true ,
321
357
} ;
322
358
}
323
359
324
360
// Filed element only
325
361
const childList = toChildrenArray ( children ) ;
326
362
if ( childList . length !== 1 || ! React . isValidElement ( childList [ 0 ] ) ) {
327
- return { child : null , isFunction : false } ;
363
+ return { child : childList , isFunction : false } ;
328
364
}
329
365
330
366
return { child : childList [ 0 ] , isFunction : false } ;
@@ -338,9 +374,18 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
338
374
} ;
339
375
340
376
public getControlled = ( childProps : ChildProps = { } ) => {
341
- const { trigger, validateTrigger, getValueFromEvent, normalize, valuePropName } = this . props ;
377
+ const {
378
+ trigger,
379
+ validateTrigger,
380
+ getValueFromEvent,
381
+ normalize,
382
+ valuePropName,
383
+ } = this . props ;
342
384
const namePath = this . getNamePath ( ) ;
343
- const { getInternalHooks, getFieldsValue } : InternalFormInstance = this . context ;
385
+ const {
386
+ getInternalHooks,
387
+ getFieldsValue,
388
+ } : InternalFormInstance = this . context ;
344
389
const { dispatch } = getInternalHooks ( HOOK_MARK ) ;
345
390
const value = this . getValue ( ) ;
346
391
@@ -412,19 +457,24 @@ class Field extends React.Component<FieldProps, FieldState> implements FieldEnti
412
457
const { children } = this . props ;
413
458
414
459
const { child, isFunction } = this . getOnlyChild ( children ) ;
415
- if ( ! child ) {
416
- // Return origin `children` if is not a function
417
- return isFunction ? child : children ;
418
- }
419
460
420
461
// Not need to `cloneElement` since user can handle this in render function self
421
- const returnChildNode = isFunction
422
- ? child
423
- : React . cloneElement ( child , this . getControlled ( child . props ) ) ;
462
+ let returnChildNode : React . ReactNode ;
463
+ if ( isFunction ) {
464
+ returnChildNode = child ;
465
+ } else if ( React . isValidElement ( child ) ) {
466
+ returnChildNode = React . cloneElement (
467
+ child as React . ReactElement ,
468
+ this . getControlled ( ( child as React . ReactElement ) . props ) ,
469
+ ) ;
470
+ } else {
471
+ warning ( ! child , '`children` of Field is not validate ReactElement.' ) ;
472
+ returnChildNode = child ;
473
+ }
424
474
425
475
// Force render a new component to reset all the data
426
476
if ( reset ) {
427
- return React . createElement ( ( ) => returnChildNode ) ;
477
+ return React . createElement ( ( ) => < > { returnChildNode } </ > ) ;
428
478
}
429
479
430
480
return returnChildNode ;
0 commit comments