Skip to content

Commit 4dce7d3

Browse files
Reimplement fix originally in rjsf-team#2199
- Replicated the fix made in rjsf-team#2199 since it is a breaking change and we are doing a bunch of them - Also updated the `CHANGELOG.md`
1 parent 13e451e commit 4dce7d3

File tree

5 files changed

+90
-21
lines changed

5 files changed

+90
-21
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ should change the heading of the (upcoming) version to include a major version b
2020
- clear errors on formData change when liveOmit=true when "additionalProperties: false" [issue 1507](https://github.com/rjsf-team/react-jsonschema-form/issues/1507) (https://github.com/rjsf-team/react-jsonschema-form/pull/2631)
2121

2222
## @rjsf/core
23-
- Fix overriding core submit button className (https://github.com/rjsf-team/react-jsonschema-form/issues/2979)
23+
- **BREAKING CHANGE** Fix overriding core submit button className (https://github.com/rjsf-team/react-jsonschema-form/issues/2979)
2424
- Fix `ui:field` with anyOf or oneOf no longer rendered twice (#2890)
25+
- **BREAKING CHANGE** Fixed `anyOf` and `oneOf` getting incorrect, potentially duplicate ids when combined with array (https://github.com/rjsf-team/react-jsonschema-form/issues/2197)
2526

2627
## @rjsf/semantic-ui
2728
- Fix missing error class on fields (https://github.com/rjsf-team/react-jsonschema-form/issues/2666)

docs/5.x upgrade guide.md

+42-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ There were several significant **breaking changes** in RJSF version 5 that were
1010
- [#2762](https://github.com/rjsf-team/react-jsonschema-form/issues/2762)
1111
- [#2858](https://github.com/rjsf-team/react-jsonschema-form/issues/2858)
1212
- [#2905](https://github.com/rjsf-team/react-jsonschema-form/issues/2905)
13-
- [#2945](https://github.com/rjsf-team/react-jsonschema-form/issues/2945)
13+
- [#2945](https://github.com/rjsf-team/react-jsonschema-form/issues/2945)
14+
- Fixed `anyOf` and `oneOf` getting incorrect, potentially duplicate ids when combined with array (https://github.com/rjsf-team/react-jsonschema-form/issues/2197)
1415

1516
### React version
1617

@@ -129,6 +130,46 @@ function YourWidget(props: WidgetProps) {
129130
}
130131
```
131132

133+
#### Generate correct ids when arrays are combined with `anyOf`/`oneOf`
134+
135+
In v4, with arrays inside `anyOf` or `oneOf`, the parent name was not used to generate ids.
136+
For example, given a schema such as:
137+
138+
```json
139+
{
140+
"type": "object",
141+
"properties": {
142+
"items": {
143+
"type": "array",
144+
"items": {
145+
"type": "object",
146+
"anyOf": [
147+
{
148+
"properties": {
149+
"foo": {
150+
"type": "string",
151+
},
152+
},
153+
},
154+
{
155+
"properties": {
156+
"bar": {
157+
"type": "string",
158+
},
159+
},
160+
},
161+
],
162+
},
163+
},
164+
},
165+
}
166+
```
167+
168+
We would get fields with id `root_foo` and `root_bar`.
169+
As you can imagine, we could end up with duplicated ids if there's actually a `foo` or a `bar` in the root of the schema.
170+
171+
From v5, the child fields will correctly use the parent id when generating its own id, generating ids such as `root_items_0_foo`.
172+
132173
### `@rjsf/material-ui` BREAKING CHANGES
133174

134175
This theme was simplified back to working only with Material UI version 4 after an unsuccessful attempt to have it fully support both versions 4 and 5 simultaneously.

packages/core/src/components/fields/SchemaField.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,13 @@ function SchemaFieldRender<T, F>(props: FieldProps<T, F>) {
172172
>("DescriptionFieldTemplate", registry, uiOptions);
173173
const schema = schemaUtils.retrieveSchema(_schema, formData);
174174
const idSchema = mergeObjects(
175-
schemaUtils.toIdSchema(schema, undefined, formData, idPrefix, idSeparator),
175+
schemaUtils.toIdSchema(
176+
schema,
177+
_idSchema.$id,
178+
formData,
179+
idPrefix,
180+
idSeparator
181+
),
176182
_idSchema
177183
) as IdSchema<T>;
178184
const FieldComponent = getFieldComponent(

packages/core/test/anyOf_test.js

+20-9
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,9 @@ describe("anyOf", () => {
810810

811811
expect(node.querySelectorAll("select")).to.have.length.of(1);
812812

813-
expect(node.querySelectorAll("input#root_foo")).to.have.length.of(1);
813+
expect(node.querySelectorAll("input#root_items_0_foo")).to.have.length.of(
814+
1
815+
);
814816
});
815817

816818
it("should not change the selected option when switching order of items for anyOf inside array items", () => {
@@ -995,8 +997,12 @@ describe("anyOf", () => {
995997
target: { value: $select.options[1].value },
996998
});
997999

998-
expect(node.querySelectorAll("input#root_foo")).to.have.length.of(1);
999-
expect(node.querySelectorAll("input#root_bar")).to.have.length.of(1);
1000+
expect(node.querySelectorAll("input#root_items_0_foo")).to.have.length.of(
1001+
1
1002+
);
1003+
expect(node.querySelectorAll("input#root_items_0_bar")).to.have.length.of(
1004+
1
1005+
);
10001006
});
10011007

10021008
it("should correctly infer the selected option based on value", () => {
@@ -1075,13 +1081,18 @@ describe("anyOf", () => {
10751081
},
10761082
});
10771083

1078-
const idSelects = node.querySelectorAll("select#root_id");
1084+
const rootId = node.querySelector("select#root_id");
1085+
expect(rootId.value).eql("chain");
1086+
const componentId = node.querySelector("select#root_components_0_id");
1087+
expect(componentId.value).eql("map");
10791088

1080-
expect(idSelects).to.have.length(4);
1081-
expect(idSelects[0].value).eql("chain");
1082-
expect(idSelects[1].value).eql("map");
1083-
expect(idSelects[2].value).eql("transform");
1084-
expect(idSelects[3].value).eql("to_absolute");
1089+
const fnId = node.querySelector("select#root_components_0_fn_id");
1090+
expect(fnId.value).eql("transform");
1091+
1092+
const transformerId = node.querySelector(
1093+
"select#root_components_0_fn_transformer_id"
1094+
);
1095+
expect(transformerId.value).eql("to_absolute");
10851096
});
10861097
});
10871098
describe("hideError works with anyOf", () => {

packages/core/test/oneOf_test.js

+19-9
Original file line numberDiff line numberDiff line change
@@ -493,8 +493,9 @@ describe("oneOf", () => {
493493
});
494494

495495
expect($select.value).eql("1");
496+
console.log(node.innerHTML);
496497

497-
Simulate.change(node.querySelector("input#root_bar"), {
498+
Simulate.change(node.querySelector("input#root_items_bar"), {
498499
target: { value: "Lorem ipsum dolor sit amet" },
499500
});
500501

@@ -584,8 +585,12 @@ describe("oneOf", () => {
584585
target: { value: $select.options[1].value },
585586
});
586587

587-
expect(node.querySelectorAll("input#root_foo")).to.have.length.of(1);
588-
expect(node.querySelectorAll("input#root_bar")).to.have.length.of(1);
588+
expect(node.querySelectorAll("input#root_items_0_foo")).to.have.length.of(
589+
1
590+
);
591+
expect(node.querySelectorAll("input#root_items_0_bar")).to.have.length.of(
592+
1
593+
);
589594
});
590595
});
591596

@@ -767,13 +772,18 @@ describe("oneOf", () => {
767772
},
768773
});
769774

770-
const idSelects = node.querySelectorAll("select#root_id");
775+
const rootId = node.querySelector("select#root_id");
776+
expect(rootId.value).eql("chain");
777+
const componentId = node.querySelector("select#root_components_0_id");
778+
expect(componentId.value).eql("map");
771779

772-
expect(idSelects).to.have.length(4);
773-
expect(idSelects[0].value).eql("chain");
774-
expect(idSelects[1].value).eql("map");
775-
expect(idSelects[2].value).eql("transform");
776-
expect(idSelects[3].value).eql("to_absolute");
780+
const fnId = node.querySelector("select#root_components_0_fn_id");
781+
expect(fnId.value).eql("transform");
782+
783+
const transformerId = node.querySelector(
784+
"select#root_components_0_fn_transformer_id"
785+
);
786+
expect(transformerId.value).eql("to_absolute");
777787
});
778788

779789
describe("Custom Field", function () {

0 commit comments

Comments
 (0)