1- import { useEffect , useContext , useState } from 'react' ;
1+ import { useEffect , useContext , useState , useRef } from 'react' ;
22import { useField } from 'react-final-form' ;
3- import useFormApi from './use-form-api' ;
43import enhancedOnChange from '../form-renderer/enhanced-on-change' ;
54import RendererContext from './renderer-context' ;
65import convertInitialValue from '../form-renderer/convert-initial-value' ;
@@ -16,43 +15,60 @@ const calculateInitialValue = (props) => {
1615 }
1716} ;
1817
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+ } ;
2923
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 ) ) ;
4127 }
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 ) ;
4237
43- enhancedProps = {
44- ... enhancedProps ,
38+ const enhancedProps = {
39+ type ,
4540 ...props ,
46- ...( initialValue ? { initialValue } : { } )
41+ ...( initialValue ? { initialValue } : { } ) ,
42+ ...( stateValidate ? { validate : stateValidate } : { } )
4743 } ;
4844
4945 const fieldProps = useField ( name , enhancedProps ) ;
5046
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+
5165 /** Re-convert initialValue when changed */
5266 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+ }
5672 }
5773 } , [ props . initialValue , props . dataType ] ) ;
5874
@@ -75,13 +91,17 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...
7591 const fieldClearedValue = Object . prototype . hasOwnProperty . call ( props , 'clearedValue' ) ? props . clearedValue : formOptions . clearedValue ;
7692
7793 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+ } ;
85105 } ,
86106 // eslint-disable-next-line react-hooks/exhaustive-deps
87107 [ ]
0 commit comments