@@ -238,6 +238,9 @@ export interface FormState<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
238
238
* `extraErrors`
239
239
*/
240
240
schemaValidationErrorSchema : ErrorSchema < T > ;
241
+ // Private
242
+ /** @description result of schemaUtils.retrieveSchema(schema, formData). This a memoized value to avoid re calculate at internal functions (getStateFromProps, onChange) */
243
+ retrievedSchema : S ;
241
244
}
242
245
243
246
/** The event data passed when changes have been made to the form, includes everything from the `FormState` except
@@ -303,7 +306,11 @@ export default class Form<
303
306
prevState : FormState < T , S , F >
304
307
) : { nextState : FormState < T , S , F > ; shouldUpdate : true } | { shouldUpdate : false } {
305
308
if ( ! deepEquals ( this . props , prevProps ) ) {
306
- const nextState = this . getStateFromProps ( this . props , this . props . formData ) ;
309
+ const nextState = this . getStateFromProps (
310
+ this . props ,
311
+ this . props . formData ,
312
+ prevProps . schema !== this . props . schema ? undefined : this . state . retrievedSchema
313
+ ) ;
307
314
const shouldUpdate = ! deepEquals ( nextState , prevState ) ;
308
315
return { nextState, shouldUpdate } ;
309
316
}
@@ -352,7 +359,7 @@ export default class Form<
352
359
* @param inputFormData - The new or current data for the `Form`
353
360
* @returns - The new state for the `Form`
354
361
*/
355
- getStateFromProps ( props : FormProps < T , S , F > , inputFormData ?: T ) : FormState < T , S , F > {
362
+ getStateFromProps ( props : FormProps < T , S , F > , inputFormData ?: T , retrievedSchema ?: S ) : FormState < T , S , F > {
356
363
const state : FormState < T , S , F > = this . state || { } ;
357
364
const schema = 'schema' in props ? props . schema : this . props . schema ;
358
365
const uiSchema : UiSchema < T , S , F > = ( 'uiSchema' in props ? props . uiSchema ! : this . props . uiSchema ! ) || { } ;
@@ -372,7 +379,7 @@ export default class Form<
372
379
schemaUtils = createSchemaUtils < T , S , F > ( props . validator , rootSchema , experimental_defaultFormStateBehavior ) ;
373
380
}
374
381
const formData : T = schemaUtils . getDefaultFormState ( schema , inputFormData ) as T ;
375
- const retrievedSchema = schemaUtils . retrieveSchema ( schema , formData ) ;
382
+ const _retrievedSchema = retrievedSchema ?? schemaUtils . retrieveSchema ( schema , formData ) ;
376
383
377
384
const getCurrentErrors = ( ) : ValidationData < T > => {
378
385
if ( props . noValidate ) {
@@ -394,7 +401,7 @@ export default class Form<
394
401
let schemaValidationErrors : RJSFValidationError [ ] = state . schemaValidationErrors ;
395
402
let schemaValidationErrorSchema : ErrorSchema < T > = state . schemaValidationErrorSchema ;
396
403
if ( mustValidate ) {
397
- const schemaValidation = this . validate ( formData , schema , schemaUtils , retrievedSchema ) ;
404
+ const schemaValidation = this . validate ( formData , schema , schemaUtils , _retrievedSchema ) ;
398
405
errors = schemaValidation . errors ;
399
406
errorSchema = schemaValidation . errorSchema ;
400
407
schemaValidationErrors = errors ;
@@ -410,7 +417,7 @@ export default class Form<
410
417
errors = merged . errors ;
411
418
}
412
419
const idSchema = schemaUtils . toIdSchema (
413
- retrievedSchema ,
420
+ _retrievedSchema ,
414
421
uiSchema [ 'ui:rootFieldId' ] ,
415
422
formData ,
416
423
props . idPrefix ,
@@ -427,6 +434,7 @@ export default class Form<
427
434
errorSchema,
428
435
schemaValidationErrors,
429
436
schemaValidationErrorSchema,
437
+ retrievedSchema : _retrievedSchema ,
430
438
} ;
431
439
return nextState ;
432
440
}
@@ -550,19 +558,21 @@ export default class Form<
550
558
*/
551
559
onChange = ( formData : T | undefined , newErrorSchema ?: ErrorSchema < T > , id ?: string ) => {
552
560
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this . props ;
553
- const { schemaUtils, schema } = this . state ;
561
+ const { schemaUtils, schema, retrievedSchema } = this . state ;
562
+
554
563
if ( isObject ( formData ) || Array . isArray ( formData ) ) {
555
- const newState = this . getStateFromProps ( this . props , formData ) ;
564
+ const newState = this . getStateFromProps ( this . props , formData , retrievedSchema ) ;
556
565
formData = newState . formData ;
557
566
}
558
567
559
568
const mustValidate = ! noValidate && liveValidate ;
560
569
let state : Partial < FormState < T , S , F > > = { formData, schema } ;
561
570
let newFormData = formData ;
562
571
572
+ let _retrievedSchema : S | undefined ;
563
573
if ( omitExtraData === true && liveOmit === true ) {
564
- const retrievedSchema = schemaUtils . retrieveSchema ( schema , formData ) ;
565
- const pathSchema = schemaUtils . toPathSchema ( retrievedSchema , '' , formData ) ;
574
+ _retrievedSchema = schemaUtils . retrieveSchema ( schema , formData ) ;
575
+ const pathSchema = schemaUtils . toPathSchema ( _retrievedSchema , '' , formData ) ;
566
576
567
577
const fieldNames = this . getFieldNames ( pathSchema , formData ) ;
568
578
@@ -573,7 +583,7 @@ export default class Form<
573
583
}
574
584
575
585
if ( mustValidate ) {
576
- const schemaValidation = this . validate ( newFormData ) ;
586
+ const schemaValidation = this . validate ( newFormData , schema , schemaUtils , retrievedSchema ) ;
577
587
let errors = schemaValidation . errors ;
578
588
let errorSchema = schemaValidation . errorSchema ;
579
589
const schemaValidationErrors = errors ;
@@ -600,6 +610,9 @@ export default class Form<
600
610
errors : toErrorList ( errorSchema ) ,
601
611
} ;
602
612
}
613
+ if ( _retrievedSchema ) {
614
+ state . retrievedSchema = _retrievedSchema ;
615
+ }
603
616
this . setState ( state as FormState < T , S , F > , ( ) => onChange && onChange ( { ...this . state , ...state } , id ) ) ;
604
617
} ;
605
618
0 commit comments