rjsf-team / react-jsonschema-form

A React component for building Web forms from JSON Schema.
https://rjsf-team.github.io/react-jsonschema-form/
Apache License 2.0
14.1k stars 2.18k forks source link

$ref object pointing to oneOf list does not update form properly when changed #3833

Open Nezteb opened 1 year ago

Nezteb commented 1 year ago

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

$ref objects pointing to objects with oneOf lists do not update properly when a user tries to change the value via dropdown.

Expected Behavior

The dropdowns should be updating properly when the user changes the value.

Steps To Reproduce

  1. Use the playground/schema below.
  2. Try to change the "Approved" dropdown to "Rejected".
  3. Note that the dropdown doesn't actually change.

Playground link: https://rjsf-team.github.io/react-jsonschema-form/#eyJmb3JtRGF0YSI6e30sInNjaGVtYSI6eyJ0aXRsZSI6Im9uZU9mIEV4YW1wbGUiLCJ0eXBlIjoib2JqZWN0IiwicHJvcGVydGllcyI6eyJzdGF0dXMiOnsiJHJlZiI6IiMvZGVmaW5pdGlvbnMvc3RhdHVzIn19LCJkZWZpbml0aW9ucyI6eyJzdGF0dXMiOnsidGl0bGUiOiJGaWVsZCBTdGF0dXMiLCJ0eXBlIjoib2JqZWN0Iiwib25lT2YiOlt7InRpdGxlIjoiQXBwcm92ZWQiLCJ0eXBlIjoib2JqZWN0In0seyJ0aXRsZSI6IlJlamVjdGVkIiwidHlwZSI6Im9iamVjdCIsInByb3BlcnRpZXMiOnsicmVhc29uIjp7InRpdGxlIjoiUmVqZWN0aW9uIFJlYXNvbiIsInR5cGUiOiJzdHJpbmcifX19XX19fSwidWlTY2hlbWEiOnt9LCJ0aGVtZSI6ImRlZmF1bHQiLCJsaXZlU2V0dGluZ3MiOnsic2hvd0Vycm9yTGlzdCI6InRvcCIsImV4cGVyaW1lbnRhbF9kZWZhdWx0Rm9ybVN0YXRlQmVoYXZpb3IiOnsiYXJyYXlNaW5JdGVtcyI6eyJwb3B1bGF0ZSI6InBvcHVsYXRlIiwibWVyZ2VFeHRyYURlZmF1bHRzIjpmYWxzZX0sImVtcHR5T2JqZWN0RmllbGRzIjoicG9wdWxhdGVBbGxEZWZhdWx0cyJ9LCJsaXZlVmFsaWRhdGUiOmZhbHNlfX0=

Schema:

{
  "title": "oneOf Example",
  "type": "object",
  "properties": {
    "status": {
      "$ref": "#/definitions/status"
    }
  },
  "definitions": {
    "status": {
      "title": "Field Status",
      "type": "object",
      "oneOf": [
        {
          "title": "Approved",
          "type": "object"
        },
        {
          "title": "Rejected",
          "type": "object",
          "properties": {
            "reason": {
              "title": "Rejection Reason",
              "type": "string"
            }
          }
        }
      ]
    }
  }
}

Environment

N/A?

Anything else?

The closest existing issues I could find to this are below, but none of them seem caused by the same problem as far as I can tell. In each of those cases, the dropdown text does update, whereas mine does not.

nickgros commented 1 year ago

@Nezteb thanks for the report and thorough issue search! This might have the same root cause as #3711, where certain properties exist in the JavaScript object representation of the form data, that you can't see in the serialized JSON form data shown in the playground. Unfortunately, maintainers' time is limited to work on every fix, so we rely on community contributions for certain issues. Would you be interested in investigating and providing a PR?

Nezteb commented 1 year ago

Would you be interested in investigating and providing a PR?

@nickgros Sure! If you have any advice of specific modules/files/classes to look at or where any relevant unit tests might be, that would go a long way in getting me started. 😄

nickgros commented 1 year ago

MultiSchemaField might be a good place to start, since the right behavior isn't happening when onOptionChange is triggered. That might lead you down to the implementations of getMatchingOption, but I'm not confident that's where the issue is.

@heath-freenome may have other ideas for what might be causing this.

heath-freenome commented 12 months ago

@Nezteb So if I select Rejected the second time it works. I know that is a crappy work-around, but it might give you a clue on how to fix it?

tyrdavis commented 10 months ago

I've now run into this issue as well. I don't believe it actually has anything to do with the $ref, but with setting the default value for an object property when a oneOf is involved. Here I've modified the schema from the original playground link to include an explicit default value on the "Rejected" member of the oneOf, and the behavior is now gone: playground link.

It seems when it doesn't know an explicit value to set the form data to, it fails to switch the oneOf option. You can notice this in the original post's playground by watching the form data; the first click of "Rejected" causes the form data to change to something that might work for that schema, then the second click successfully changes.

Like I mentioned, you can remove the definition and $ref entirely, defining the schema directly inside properties and see both of these behaviors (with and without default defined).

heath-freenome commented 10 months ago

@tyrdavis Is this something you feel comfortable fixing for us?