Skip to content

Commit db369ed

Browse files
committed
Store initialValue in state to keep references
1 parent 3194dd3 commit db369ed

File tree

2 files changed

+39
-28
lines changed

2 files changed

+39
-28
lines changed

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

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useContext } from 'react';
1+
import { useEffect, useContext, useState } from 'react';
22
import { useField } from 'react-final-form';
33
import useFormApi from './use-form-api';
44
import enhancedOnChange from '../form-renderer/enhanced-on-change';
@@ -8,25 +8,25 @@ import assignSpecialType from '../form-renderer/assign-special-type';
88
import componentTypes from './component-types';
99
import { prepareArrayValidator, getValidate } from '../form-renderer/validator-helpers';
1010
import composeValidators from './compose-validators';
11+
import isEqual from 'lodash/isEqual';
1112

12-
const useFieldApi = ({ name, initializeOnMount, component, render, validate, type, ...props }) => {
13+
const calculateInitialValue = (props) => {
14+
if (Object.prototype.hasOwnProperty.call(props, 'initialValue') && Object.prototype.hasOwnProperty.call(props, 'dataType')) {
15+
return convertInitialValue(props.initialValue, props.dataType);
16+
}
17+
};
18+
19+
const useFieldApi = ({ name, initializeOnMount, component, render, validate, ...props }) => {
1320
const { actionMapper, validatorMapper } = useContext(RendererContext);
21+
const [initialValue, setInitialValue] = useState(() => calculateInitialValue(props));
1422

1523
const formOptions = useFormApi();
1624

1725
/** Assign type (checkbox, radio ) */
1826
let enhancedProps = {
19-
type: type || assignSpecialType(component)
27+
type: assignSpecialType(component)
2028
};
2129

22-
/** Convert initialValue to correct dataType */
23-
if (Object.prototype.hasOwnProperty.call(props, 'initialValue') && Object.prototype.hasOwnProperty.call(props, 'dataType')) {
24-
enhancedProps = {
25-
...enhancedProps,
26-
initialValue: convertInitialValue(props.initialValue, props.dataType)
27-
};
28-
}
29-
3030
/** Add validate/array validator when needed */
3131
let arrayValidator;
3232
if (validate || props.dataType) {
@@ -41,24 +41,33 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, typ
4141
}
4242

4343
enhancedProps = {
44+
...enhancedProps,
4445
...props,
45-
...enhancedProps
46+
...(initialValue ? { initialValue } : {})
4647
};
4748

4849
const fieldProps = useField(name, enhancedProps);
4950

51+
/** Re-convert initialValue when changed */
52+
useEffect(() => {
53+
const newInitialValue = calculateInitialValue(props);
54+
if (!isEqual(initialValue, newInitialValue)) {
55+
setInitialValue(newInitialValue);
56+
}
57+
}, [props.initialValue, props.dataType]);
58+
5059
useEffect(() => {
5160
/**
5261
* Re initialize field when mounted to the Form
5362
* This affects conditional fields
5463
*/
5564
if (initializeOnMount) {
56-
const initialValue = Object.prototype.hasOwnProperty.call(enhancedProps, 'initialValue')
65+
const value = Object.prototype.hasOwnProperty.call(enhancedProps, 'initialValue')
5766
? enhancedProps.initialValue
5867
: formOptions.getFieldState(name).initial;
59-
fieldProps.input.onChange(initialValue);
68+
fieldProps.input.onChange(value);
6069
}
61-
}, [initializeOnMount, enhancedProps.initialValue, fieldProps.meta.initial]);
70+
}, [initializeOnMount, enhancedProps.initialValue, fieldProps.meta.initial, props.dataType]);
6271

6372
/**
6473
* Prepare deleted value of field
@@ -89,7 +98,7 @@ const useFieldApi = ({ name, initializeOnMount, component, render, validate, typ
8998
});
9099
}
91100

92-
const { initialValue, clearOnUnmount, dataType, ...cleanProps } = props;
101+
const { initialValue: _initialValue, clearOnUnmount, dataType, clearedValue, ...cleanProps } = props;
93102

94103
/**
95104
* construct component props necessary that would live in field provider

packages/react-form-renderer/src/tests/form-renderer/render-form.test.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ describe('renderForm function', () => {
744744
{
745745
component,
746746
name: 'unmnounted',
747+
key: 'unmnounted-1',
747748
label: 'Label 1',
748749
clearOnUnmount,
749750
condition: {
@@ -754,6 +755,7 @@ describe('renderForm function', () => {
754755
{
755756
component,
756757
name: 'unmnounted',
758+
key: 'unmnounted-2',
757759
label: 'Label 2',
758760
clearOnUnmount,
759761
condition: {
@@ -1182,23 +1184,22 @@ describe('renderForm function', () => {
11821184
const form = wrapper.find('form');
11831185
form.simulate('submit');
11841186
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: INITIAL_VALUE }));
1187+
onSubmit.mockReset();
11851188

11861189
mountInitializedField(wrapper);
11871190
setInitializedToNewValue(wrapper);
1188-
onSubmit.mockReset();
1189-
11901191
form.simulate('submit');
1191-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: INITIAL_VALUE, [SHOWER_FIELD]: SHOW_VALUE }));
1192+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: NEW_VALUE, [SHOWER_FIELD]: SHOW_VALUE }));
11921193
onSubmit.mockReset();
11931194

1194-
form.simulate('submit');
11951195
unmountInitializedField(wrapper);
1196-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: INITIAL_VALUE, [SHOWER_FIELD]: SHOW_VALUE }));
1196+
form.simulate('submit');
1197+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: NEW_VALUE, [SHOWER_FIELD]: NOT_SHOW_VALUE }));
11971198
onSubmit.mockReset();
11981199

1199-
form.simulate('submit');
12001200
mountInitializedField(wrapper);
1201-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: INITIAL_VALUE, [SHOWER_FIELD]: NOT_SHOW_VALUE }));
1201+
form.simulate('submit');
1202+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: INITIAL_VALUE, [SHOWER_FIELD]: SHOW_VALUE }));
12021203
});
12031204

12041205
it('should not reset value after mount when set on fields', () => {
@@ -1262,12 +1263,12 @@ describe('renderForm function', () => {
12621263
mountInitializedField(wrapper);
12631264
setInitializedToNewValue(wrapper);
12641265
wrapper.find('form').simulate('submit');
1265-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [SHOWER_FIELD]: SHOW_VALUE, [INITIALIZED_FIELD]: SCHEMA_INITIAL_VALUE }));
1266+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [SHOWER_FIELD]: SHOW_VALUE, [INITIALIZED_FIELD]: NEW_VALUE }));
12661267
onSubmit.mockReset();
12671268

12681269
unmountInitializedField(wrapper);
12691270
wrapper.find('form').simulate('submit');
1270-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [SHOWER_FIELD]: NOT_SHOW_VALUE, [INITIALIZED_FIELD]: SCHEMA_INITIAL_VALUE }));
1271+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [SHOWER_FIELD]: NOT_SHOW_VALUE, [INITIALIZED_FIELD]: NEW_VALUE }));
12711272
onSubmit.mockReset();
12721273

12731274
mountInitializedField(wrapper);
@@ -1294,12 +1295,12 @@ describe('renderForm function', () => {
12941295
mountInitializedField(wrapper);
12951296
setInitializedToNewValue(wrapper);
12961297
wrapper.find('form').simulate('submit');
1297-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [SHOWER_FIELD]: SHOW_VALUE, [INITIALIZED_FIELD]: SCHEMA_INITIAL_VALUE }));
1298+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [SHOWER_FIELD]: SHOW_VALUE, [INITIALIZED_FIELD]: NEW_VALUE }));
12981299
onSubmit.mockReset();
12991300

13001301
unmountInitializedField(wrapper);
13011302
wrapper.find('form').simulate('submit');
1302-
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: SCHEMA_INITIAL_VALUE, [SHOWER_FIELD]: NOT_SHOW_VALUE }));
1303+
expect(onSubmit).toHaveBeenCalledWith(expect.objectContaining({ [INITIALIZED_FIELD]: NEW_VALUE, [SHOWER_FIELD]: NOT_SHOW_VALUE }));
13031304
onSubmit.mockReset();
13041305

13051306
mountInitializedField(wrapper);
@@ -1328,6 +1329,7 @@ describe('renderForm function', () => {
13281329
{
13291330
component: componentTypes.TEXT_FIELD,
13301331
name: 'unmounted',
1332+
key: 'unmounted-2',
13311333
initialValue: true,
13321334
initializeOnMount: true,
13331335
condition: {
@@ -1500,7 +1502,7 @@ describe('renderForm function', () => {
15001502
).toEqual('standard label');
15011503
});
15021504

1503-
describe('composite mapper component', () => {
1505+
it('composite mapper component', () => {
15041506
const schema = {
15051507
fields: [
15061508
{

0 commit comments

Comments
 (0)