Skip to content

Nested schema and conditionally setting the default field value using resolveProps results in a warning #1249

@rustoma

Description

@rustoma

Scope: form-renderer

Description

I have a fairly complex form with nested fields. I use resolveProps to determine the default value. Using formOptions.change() results in a warning as below.

Calling this method using setTimeout does not display the warning.

I know there used to be a similar problem related to React 16 and react-final-form, but I can't find a solution anywhere.

I would expect that using formOptions.change() in resolveProps would not result in a warning.

Using data-driven-forms with resolveProps results in a warning:

Warning: Cannot update a component (`FieldArray`) while rendering a different component (`Radio`). To locate the bad setState() call inside `Radio`, follow the stack trace as described in https://fb.me/setstate-in-render
    in Radio (created by SingleField)
    in FormFieldHideWrapper (created by SingleField)
    in FormConditionWrapper (created by SingleField)
    in SingleField (created by ArrayItem)
    in ArrayItem (at FieldArrayCustom.tsx:91)
    in FieldArray (at FieldArrayCustom.tsx:65)
    in FieldArrayCustom (created by SingleField)
    in FormFieldHideWrapper (created by SingleField)
    in FormConditionWrapper (created by SingleField)
    in SingleField (created by ArrayItem)
    in ArrayItem (at FieldArrayCustom.tsx:91)
    in FieldArray (at FieldArrayCustom.tsx:65)

Schema

The schema looks similar to the one below

const schema = {
  component: CustomComponentTypesEnum.ARRAY_STEPS,
  name: 'array_1',
  fieldKey: 'field_array',
  fields: [
    {
      component: CustomComponentTypesEnum.ARRAY_CUSTOM,
      name: 'array_2',
      fieldKey: 'field_array_tabs',
      fields: [
        {
          component: componentTypes.RADIO,
          name: 'name_x',
          label: '',
          options: [
            {
              label: 'Label 1',
              value: 'value_1',
            },
            { label: 'Label 2', value: 'value_2' },
          ],
        },
        {
          component: CustomComponentTypesEnum.ARRAY_CUSTOM,
          name: 'name_y',
          fieldKey: 'field_name_y',

          fields: [
            {
              component: componentTypes.RADIO,
              name: 'radio_1',
              label: '',
              options: [
                {
                  label: 'Label 1',
                  value: 'value_1',
                },
                { label: 'Label 2', value: 'value_2' },
              ],

              resolveProps: (_props, _field, formOptions) => {
                const setFieldDefaultValue = setDefaultValue(
                  formOptions,
                  _field.input.name,
                )

                // Logic to determine conditions
                //   ...

                //If some conditions are met trigger function
                if (someConditionsAreMet) {
                  setFieldDefaultValue(example_value')
                }
              },
            },
          ],
        },
      ],
    },
  ],
}
const setDefaultValue = (form, fieldName) => (value) => {
  if (!_.get(form.getState().values, fieldName)) {
    // Without setTimeout I get a warning
    form.change(fieldName, value)

    // With setTimeout everything is ok
    setTimeout(() => form.change(fieldName, value), 0)
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions