1
- import { useEffect , useContext , useState , useRef } from 'react' ;
1
+ import { useEffect , useContext , useRef , useReducer } from 'react' ;
2
2
import { useField } from 'react-final-form' ;
3
3
import enhancedOnChange from '../form-renderer/enhanced-on-change' ;
4
4
import RendererContext from './renderer-context' ;
@@ -27,12 +27,45 @@ const calculateValidate = (props, validate, component, validatorMapper) => {
27
27
}
28
28
} ;
29
29
30
+ const init = ( { props, validate, component, validatorMapper } ) => ( {
31
+ initialValue : calculateInitialValue ( props ) ,
32
+ arrayValidator : calculateArrayValidator ( props , validate , component , validatorMapper ) ,
33
+ validate : calculateValidate ( props , validate , component , validatorMapper ) ,
34
+ type : assignSpecialType ( component )
35
+ } ) ;
36
+
37
+ const reducer = ( state , { type, specialType, validate, arrayValidator, initialValue } ) => {
38
+ switch ( type ) {
39
+ case 'setType' :
40
+ return {
41
+ ...state ,
42
+ type : specialType
43
+ } ;
44
+ case 'setValidators' :
45
+ return {
46
+ ...state ,
47
+ validate,
48
+ arrayValidator
49
+ } ;
50
+ case 'setInitialValue' :
51
+ return {
52
+ ...state ,
53
+ initialValue
54
+ } ;
55
+ default :
56
+ return state ;
57
+ }
58
+ } ;
59
+
30
60
const useFieldApi = ( { name, initializeOnMount, component, render, validate, ...props } ) => {
31
61
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 ) ) ;
62
+
63
+ const [ { type, initialValue, validate : stateValidate , arrayValidator } , dispatch ] = useReducer (
64
+ reducer ,
65
+ { props, validate, component, validatorMapper } ,
66
+ init
67
+ ) ;
68
+
36
69
const mounted = useRef ( false ) ;
37
70
38
71
const enhancedProps = {
@@ -49,16 +82,19 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
49
82
if ( mounted . current ) {
50
83
const specialType = assignSpecialType ( component ) ;
51
84
if ( specialType !== type ) {
52
- setType ( specialType ) ;
85
+ dispatch ( { type : 'setType' , specialType } ) ;
53
86
}
54
87
}
55
88
} , [ component ] ) ;
56
89
57
90
/** Reinitilize array validator/validate */
58
91
useEffect ( ( ) => {
59
92
if ( mounted . current ) {
60
- setArrayValidator ( calculateArrayValidator ( props , validate , component , validatorMapper ) ) ;
61
- setValidate ( calculateValidate ( props , validate , component , validatorMapper ) ) ;
93
+ dispatch ( {
94
+ type : 'setValidators' ,
95
+ validate : calculateValidate ( props , validate , component , validatorMapper ) ,
96
+ arrayValidator : calculateArrayValidator ( props , validate , component , validatorMapper )
97
+ } ) ;
62
98
}
63
99
} , [ validate , component , props . dataType ] ) ;
64
100
@@ -67,7 +103,10 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
67
103
if ( mounted . current ) {
68
104
const newInitialValue = calculateInitialValue ( props ) ;
69
105
if ( ! isEqual ( initialValue , newInitialValue ) ) {
70
- setInitialValue ( newInitialValue ) ;
106
+ dispatch ( {
107
+ type : 'setInitialValue' ,
108
+ initialValue : newInitialValue
109
+ } ) ;
71
110
}
72
111
}
73
112
} , [ props . initialValue , props . dataType ] ) ;
@@ -95,6 +134,7 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
95
134
mounted . current = true ;
96
135
97
136
return ( ) => {
137
+ mounted . current = false ;
98
138
/**
99
139
* Delete the value from form state when field is inmounted
100
140
*/
0 commit comments