1
- import { useEffect , useContext , useState } from 'react' ;
1
+ import { useEffect , useContext , useState , useRef } from 'react' ;
2
2
import { useField } from 'react-final-form' ;
3
- import useFormApi from './use-form-api' ;
4
3
import enhancedOnChange from '../form-renderer/enhanced-on-change' ;
5
4
import RendererContext from './renderer-context' ;
6
5
import convertInitialValue from '../form-renderer/convert-initial-value' ;
@@ -16,43 +15,60 @@ const calculateInitialValue = (props) => {
16
15
}
17
16
} ;
18
17
19
- const useFieldApi = ( { name, initializeOnMount, component, render, validate, ...props } ) => {
20
- const { actionMapper, validatorMapper } = useContext ( RendererContext ) ;
21
- const [ initialValue , setInitialValue ] = useState ( ( ) => calculateInitialValue ( props ) ) ;
22
-
23
- const formOptions = useFormApi ( ) ;
24
-
25
- /** Assign type (checkbox, radio ) */
26
- let enhancedProps = {
27
- type : assignSpecialType ( component )
28
- } ;
18
+ const calculateArrayValidator = ( props , validate , component , validatorMapper ) => {
19
+ if ( ( validate || props . dataType ) && componentTypes . FIELD_ARRAY === component ) {
20
+ return prepareArrayValidator ( getValidate ( validate , props . dataType , validatorMapper ) ) ;
21
+ }
22
+ } ;
29
23
30
- /** Add validate/array validator when needed */
31
- let arrayValidator ;
32
- if ( validate || props . dataType ) {
33
- if ( componentTypes . FIELD_ARRAY === component ) {
34
- arrayValidator = prepareArrayValidator ( getValidate ( validate , props . dataType , validatorMapper ) ) ;
35
- } else {
36
- enhancedProps = {
37
- ...enhancedProps ,
38
- validate : composeValidators ( getValidate ( validate , props . dataType , validatorMapper ) )
39
- } ;
40
- }
24
+ const calculateValidate = ( props , validate , component , validatorMapper ) => {
25
+ if ( ( validate || props . dataType ) && componentTypes . FIELD_ARRAY !== component ) {
26
+ return composeValidators ( getValidate ( validate , props . dataType , validatorMapper ) ) ;
41
27
}
28
+ } ;
29
+
30
+ const useFieldApi = ( { name, initializeOnMount, component, render, validate, ...props } ) => {
31
+ const { actionMapper, validatorMapper, formOptions } = useContext ( RendererContext ) ;
32
+ const [ initialValue , setInitialValue ] = useState ( ( ) => calculateInitialValue ( props ) ) ;
33
+ const [ arrayValidator , setArrayValidator ] = useState ( ( ) => calculateArrayValidator ( props , validate , component , validatorMapper ) ) ;
34
+ const [ stateValidate , setValidate ] = useState ( ( ) => calculateValidate ( props , validate , component , validatorMapper ) ) ;
35
+ const [ type , setType ] = useState ( ( ) => assignSpecialType ( component ) ) ;
36
+ const mounted = useRef ( false ) ;
42
37
43
- enhancedProps = {
44
- ... enhancedProps ,
38
+ const enhancedProps = {
39
+ type ,
45
40
...props ,
46
- ...( initialValue ? { initialValue } : { } )
41
+ ...( initialValue ? { initialValue } : { } ) ,
42
+ ...( stateValidate ? { validate : stateValidate } : { } )
47
43
} ;
48
44
49
45
const fieldProps = useField ( name , enhancedProps ) ;
50
46
47
+ /** Reinitilize type */
48
+ useEffect ( ( ) => {
49
+ if ( mounted . current ) {
50
+ const specialType = assignSpecialType ( component ) ;
51
+ if ( specialType !== type ) {
52
+ setType ( specialType ) ;
53
+ }
54
+ }
55
+ } , [ component ] ) ;
56
+
57
+ /** Reinitilize array validator/validate */
58
+ useEffect ( ( ) => {
59
+ if ( mounted . current ) {
60
+ setArrayValidator ( calculateArrayValidator ( props , validate , component , validatorMapper ) ) ;
61
+ setValidate ( calculateValidate ( props , validate , component , validatorMapper ) ) ;
62
+ }
63
+ } , [ validate , component , props . dataType ] ) ;
64
+
51
65
/** Re-convert initialValue when changed */
52
66
useEffect ( ( ) => {
53
- const newInitialValue = calculateInitialValue ( props ) ;
54
- if ( ! isEqual ( initialValue , newInitialValue ) ) {
55
- setInitialValue ( newInitialValue ) ;
67
+ if ( mounted . current ) {
68
+ const newInitialValue = calculateInitialValue ( props ) ;
69
+ if ( ! isEqual ( initialValue , newInitialValue ) ) {
70
+ setInitialValue ( newInitialValue ) ;
71
+ }
56
72
}
57
73
} , [ props . initialValue , props . dataType ] ) ;
58
74
@@ -75,13 +91,17 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
75
91
const fieldClearedValue = Object . prototype . hasOwnProperty . call ( props , 'clearedValue' ) ? props . clearedValue : formOptions . clearedValue ;
76
92
77
93
useEffect (
78
- ( ) => ( ) => {
79
- /**
80
- * Delete the value from form state when field is inmounted
81
- */
82
- if ( ( formOptions . clearOnUnmount || props . clearOnUnmount ) && props . clearOnUnmount !== false ) {
83
- fieldProps . input . onChange ( fieldClearedValue ) ;
84
- }
94
+ ( ) => {
95
+ mounted . current = true ;
96
+
97
+ return ( ) => {
98
+ /**
99
+ * Delete the value from form state when field is inmounted
100
+ */
101
+ if ( ( formOptions . clearOnUnmount || props . clearOnUnmount ) && props . clearOnUnmount !== false ) {
102
+ fieldProps . input . onChange ( fieldClearedValue ) ;
103
+ }
104
+ } ;
85
105
} ,
86
106
// eslint-disable-next-line react-hooks/exhaustive-deps
87
107
[ ]
0 commit comments