1
1
import * as React from 'react' ;
2
- import warning from 'warning' ;
2
+ import warning from 'rc-util/lib/ warning' ;
3
3
import {
4
4
Callbacks ,
5
5
FieldData ,
@@ -308,12 +308,100 @@ export class FormStore {
308
308
return this . isFieldsValidating ( [ name ] ) ;
309
309
} ;
310
310
311
+ /**
312
+ * Reset Field with field `initialValue` prop.
313
+ * Can pass `entities` or `namePathList` or just nothing.
314
+ */
315
+ private resetWithFieldInitialValue = (
316
+ info : {
317
+ entities ?: FieldEntity [ ] ;
318
+ namePathList ?: InternalNamePath [ ] ;
319
+ /** Skip reset if store exist value. This is only used for field register reset */
320
+ skipExist ?: boolean ;
321
+ } = { } ,
322
+ ) => {
323
+ // Create cache
324
+ const cache : NameMap < Set < { entity : FieldEntity ; value : any } > > = new NameMap ( ) ;
325
+
326
+ const fieldEntities = this . getFieldEntities ( true ) ;
327
+ fieldEntities . forEach ( field => {
328
+ const { initialValue } = field . props ;
329
+ const namePath = field . getNamePath ( ) ;
330
+
331
+ // Record only if has `initialValue`
332
+ if ( initialValue !== undefined ) {
333
+ const records = cache . get ( namePath ) || new Set ( ) ;
334
+ records . add ( { entity : field , value : initialValue } ) ;
335
+
336
+ cache . set ( namePath , records ) ;
337
+ }
338
+ } ) ;
339
+
340
+ // Reset
341
+ const resetWithFields = ( entities : FieldEntity [ ] ) => {
342
+ entities . forEach ( field => {
343
+ const { initialValue } = field . props ;
344
+
345
+ if ( initialValue !== undefined ) {
346
+ const namePath = field . getNamePath ( ) ;
347
+ const formInitialValue = this . getInitialValue ( namePath ) ;
348
+
349
+ if ( formInitialValue !== undefined ) {
350
+ // Warning if conflict with form initialValues and do not modify value
351
+ warning (
352
+ false ,
353
+ `Form already set 'initialValues' with path '${ namePath . join (
354
+ '.' ,
355
+ ) } '. Field can not overwrite it.`,
356
+ ) ;
357
+ } else {
358
+ const records = cache . get ( namePath ) ;
359
+ if ( records && records . size > 1 ) {
360
+ // Warning if multiple field set `initialValue`and do not modify value
361
+ warning (
362
+ false ,
363
+ `Multiple Field with path '${ namePath . join (
364
+ '.' ,
365
+ ) } ' set 'initialValue'. Can not decide which one to pick.`,
366
+ ) ;
367
+ } else if ( records ) {
368
+ const originValue = this . getFieldValue ( namePath ) ;
369
+ // Set `initialValue`
370
+ if ( ! info . skipExist || originValue === undefined ) {
371
+ this . store = setValue ( this . store , namePath , [ ...records ] [ 0 ] . value ) ;
372
+ }
373
+ }
374
+ }
375
+ }
376
+ } ) ;
377
+ } ;
378
+
379
+ let requiredFieldEntities : FieldEntity [ ] ;
380
+ if ( info . entities ) {
381
+ requiredFieldEntities = info . entities ;
382
+ } else if ( info . namePathList ) {
383
+ requiredFieldEntities = [ ] ;
384
+
385
+ info . namePathList . forEach ( namePath => {
386
+ const records = cache . get ( namePath ) ;
387
+ if ( records ) {
388
+ requiredFieldEntities . push ( ...[ ...records ] . map ( r => r . entity ) ) ;
389
+ }
390
+ } ) ;
391
+ } else {
392
+ requiredFieldEntities = fieldEntities ;
393
+ }
394
+
395
+ resetWithFields ( requiredFieldEntities ) ;
396
+ } ;
397
+
311
398
private resetFields = ( nameList ?: NamePath [ ] ) => {
312
399
this . warningUnhooked ( ) ;
313
400
314
401
const prevStore = this . store ;
315
402
if ( ! nameList ) {
316
403
this . store = setValues ( { } , this . initialValues ) ;
404
+ this . resetWithFieldInitialValue ( ) ;
317
405
this . notifyObservers ( prevStore , null , { type : 'reset' } ) ;
318
406
return ;
319
407
}
@@ -324,6 +412,7 @@ export class FormStore {
324
412
const initialValue = this . getInitialValue ( namePath ) ;
325
413
this . store = setValue ( this . store , namePath , initialValue ) ;
326
414
} ) ;
415
+ this . resetWithFieldInitialValue ( { namePathList } ) ;
327
416
this . notifyObservers ( prevStore , namePathList , { type : 'reset' } ) ;
328
417
} ;
329
418
@@ -371,6 +460,17 @@ export class FormStore {
371
460
private registerField = ( entity : FieldEntity ) => {
372
461
this . fieldEntities . push ( entity ) ;
373
462
463
+ // Set initial values
464
+ if ( entity . props . initialValue !== undefined ) {
465
+ const prevStore = this . store ;
466
+ this . resetWithFieldInitialValue ( { entities : [ entity ] , skipExist : true } ) ;
467
+ this . notifyObservers ( prevStore , [ entity . getNamePath ( ) ] , {
468
+ type : 'valueUpdate' ,
469
+ source : 'internal' ,
470
+ } ) ;
471
+ }
472
+
473
+ // un-register field callback
374
474
return ( ) => {
375
475
this . fieldEntities = this . fieldEntities . filter ( item => item !== entity ) ;
376
476
} ;
0 commit comments