Skip to content

Commit 556bfeb

Browse files
committed
Optimize useFieldApi
1 parent 1c7db73 commit 556bfeb

File tree

1 file changed

+56
-36
lines changed

1 file changed

+56
-36
lines changed

packages/react-form-renderer/src/files/use-field-api.js

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { useEffect, useContext, useState } from 'react';
1+
import { useEffect, useContext, useState, useRef } from 'react';
22
import { useField } from 'react-final-form';
3-
import useFormApi from './use-form-api';
43
import enhancedOnChange from '../form-renderer/enhanced-on-change';
54
import RendererContext from './renderer-context';
65
import 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

Comments
 (0)