Skip to content

Commit aa7fdf7

Browse files
authored
Merge pull request #1231 from rvsia/cloneValuesInCondition
Deep clone values in condition to prevent reference issues
2 parents 1664639 + 8d5514c commit aa7fdf7

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useContext } from 'react';
22
import PropTypes from 'prop-types';
33
import setWith from 'lodash/setWith';
4+
import cloneDeep from 'lodash/cloneDeep';
45
import { Field } from 'react-final-form';
56
import RendererContext from '../renderer-context';
67
import Condition from '../condition';
@@ -47,7 +48,7 @@ const ConditionTriggerDetector = ({ values = {}, triggers = [], children, condit
4748
{({ input: { value } }) => (
4849
<ConditionTriggerDetector
4950
triggers={[...internalTriggers]}
50-
values={setWith({ ...values }, name, value, Object)}
51+
values={setWith(cloneDeep(values), name, value, Object)}
5152
condition={condition}
5253
field={field}
5354
>

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

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { act, render, screen } from '@testing-library/react';
2+
import { act, render, screen, waitFor } from '@testing-library/react';
33
import userEvent from '@testing-library/user-event';
44

55
import FormTemplate from '../../../../../__mocks__/mock-form-template';
@@ -468,6 +468,59 @@ describe('condition test', () => {
468468
expect(() => screen.getByLabelText('field-2')).toThrow();
469469
});
470470

471+
it('should handle nested complex coniditions', async () => {
472+
const schema = {
473+
fields: [
474+
{
475+
component: 'text-field',
476+
name: 'info.name.last',
477+
label: 'last name',
478+
},
479+
{
480+
component: 'text-field',
481+
name: 'info.name.father',
482+
label: 'Father name',
483+
},
484+
{
485+
component: 'text-field',
486+
name: 'info.name.equipment',
487+
label: 'Equipment name',
488+
},
489+
{
490+
component: 'text-field',
491+
name: 'info.occupation',
492+
label: 'occupation',
493+
condition: {
494+
sequence: [
495+
{
496+
and: [
497+
{
498+
or: [
499+
{ when: 'info.name.father', is: 'Charles' },
500+
{ when: 'info.name.equipment', is: 'Gun' },
501+
],
502+
},
503+
{ when: 'info.name.last', is: 'Bond' },
504+
],
505+
then: {
506+
set: { 'info.occupation': 'SPY' },
507+
},
508+
else: { visible: true },
509+
},
510+
],
511+
},
512+
},
513+
],
514+
};
515+
516+
render(<FormRenderer {...initialProps} schema={schema} />);
517+
518+
userEvent.type(screen.getByLabelText('info.name.last'), 'Bond');
519+
userEvent.type(screen.getByLabelText('info.name.equipment'), 'Gun');
520+
521+
await waitFor(() => expect(screen.getByLabelText('info.occupation')).toHaveValue('SPY'));
522+
});
523+
471524
describe('reducer', () => {
472525
it('returns default', () => {
473526
const initialState = {

0 commit comments

Comments
 (0)