react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

Live validation / onChange errors issue

Open AlimovSV opened this issue 1 year ago • 5 comments

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

when schema contains if/then/else and a user's changes activates then/else subschemas, the live validation works but errors in the onChange event are not reflect the real ones

Expected Behavior

errors in the onChange event should always reflect the form state

Steps To Reproduce

Thus, open the repo https://github.com/AlimovSV/rjsf-onchange-issue and click checkbox, you will see error message in the UI but console.log in the onChange event handler displays empty array:

Next uncheck the checkbox you will see that form becomes valid but console log displays errors from the previous form state:

Environment

- OS:
- Node:
- npm:

Anything else?

No response

AlimovSV avatar Jul 10 '24 12:07 AlimovSV

Just another addition: when the schema is nested - all work fine.

AlimovSV avatar Jul 10 '24 12:07 AlimovSV

This reproduces in this playground link (Playground.tsx needs to be updated to log the errors onChange)

@AlimovSV What's the nested schema that seems to work for you? I see the same issue if I wrap the if & then schemas in an "allOf": [{ ... }]

Also interesting is that the text field in the same example does not have this issue

nickgros avatar Jul 12 '24 20:07 nickgros

@nickgros The workable schema is

{
  "type": "object",
  "properties": {
    "root": {
      "type": "object",
      "required": [
        "checkbox"
      ],
      "properties": {
        "checkbox": {
          "type": "boolean"
        }
      },
      "if": {
        "required": [
          "checkbox"
        ],
        "properties": {
          "checkbox": {
            "const": true
          }
        }
      },
      "then": {
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string"
          }
        }
      }
    }
  }
}

AlimovSV avatar Jul 15 '24 06:07 AlimovSV

I guess the problem is in this line: https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/core/src/components/Form.tsx#L617 - the form validation is proceeding with the old retrieved schema, that will be updated on the next render and we observe "delay" for one user's change. So the changes works for me:

    this.onChange = (formData, newErrorSchema, id) => {
      const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
[-]   const { schemaUtils, schema, retrievedSchema } = this.state;
[+]   const { schemaUtils, schema } = this.state;
[+]   let retrievedSchema;
      if ((0, import_utils39.isObject)(formData) || Array.isArray(formData)) {
[-]     const newState = this.getStateFromProps(this.props, formData, retrievedSchema);
[+]     const newState = this.getStateFromProps(this.props, formData);
        formData = newState.formData;
[+]     retrievedSchema = newState.retrievedSchema;
      }

I'm not sure about how these changes will affect the performance, because we retrieve the schema on every form change. @nickgros thoughts?

AlimovSV avatar Jul 30 '24 10:07 AlimovSV

Also I concern about calling getStateFromProps inside the onChange. Looks like we do a validation twice, when liveValidation is on.

AlimovSV avatar Jul 30 '24 10:07 AlimovSV

Any updates?

AlimovSV avatar Oct 22 '24 07:10 AlimovSV