Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FED-202 Return jsUndefined instead of null when children prop is empty #350

Merged
merged 3 commits into from Dec 6, 2022

Conversation

sydneyjodon-wk
Copy link
Collaborator

@sydneyjodon-wk sydneyjodon-wk commented Dec 5, 2022

Some JS components, like Tab expect no children to be passed to them.

However, when rendered from Dart, Tab's propTypes warn about children not being supported, even when no children are provided:

react.js:6902 Warning: Failed prop type: The prop `children` is not supported. Please remove it.
    at Tab (http://localhost:8080/packages/react_material_ui/react-material-ui-development.umd.js:46607:19)

This is because, when there are no children, ReactJsComponentFactoryProxy passes null into createElement, and the unsupportedProp validation checks warns when the prop is undefined.

Changes

  • Return jsUndefined instead of null from generateChildren when the children prop is empty
  • Add regression test

QA Instructions

  • Verify CI passes
  • Verify good test coverage

@aviary-wf
Copy link

Security Insights

No security relevant content was detected by automated scans.

Action Items

  • Review PR for security impact; comment "security review required" if needed or unsure
  • Verify aviary.yaml coverage of security relevant code

Questions or Comments? Reach out on Slack: #support-infosec.

Comment on lines 13 to 15
if(this.props.children !== undefined) {
throw Error('children prop must be undefined');
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if there's a more straightforward way to test that props.children is specifically undefined and not null - open to suggestions

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought maybe we could change this expectation:

-expect(getChildren(instance), shouldAlwaysBeList ? [] : isNull);
+// We want to make sure this is undefined and not null, so we have to use `same`
+// which uses `identical`, since in Dart null and undefined are otherwise interchangeable.
+expect(getChildren(instance), shouldAlwaysBeList ? [] : same(jsUndefined));

But it looks like that doesn't even work, since the identical check gets compiled to == instead of === , and identical(jsNull, jsUndefined) is true 😕.

So, checking it from the JS seems like the way to go to me!

Related to my comment above, we could also potentially check whether it's undefined on the ReactElement without rendering it, if the rendering/throwing causes issues or complicates things.

window.hasUndefinedChildren = (reactElement) => reactElement.props.children === undefined;
 expect(hasUndefinedChildren(JsNoChildren({})), isTrue);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's a lot nicer! Thank you!

@sydneyjodon-wk sydneyjodon-wk requested review from a team and aaronlademann-wf and removed request for a team December 5, 2022 19:04
@sydneyjodon-wk sydneyjodon-wk marked this pull request as ready for review December 5, 2022 19:05
Copy link
Collaborator

@aaronlademann-wf aaronlademann-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Comment on lines 13 to 15
if(this.props.children !== undefined) {
throw Error('children prop must be undefined');
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought maybe we could change this expectation:

-expect(getChildren(instance), shouldAlwaysBeList ? [] : isNull);
+// We want to make sure this is undefined and not null, so we have to use `same`
+// which uses `identical`, since in Dart null and undefined are otherwise interchangeable.
+expect(getChildren(instance), shouldAlwaysBeList ? [] : same(jsUndefined));

But it looks like that doesn't even work, since the identical check gets compiled to == instead of === , and identical(jsNull, jsUndefined) is true 😕.

So, checking it from the JS seems like the way to go to me!

Related to my comment above, we could also potentially check whether it's undefined on the ReactElement without rendering it, if the rendering/throwing causes issues or complicates things.

window.hasUndefinedChildren = (reactElement) => reactElement.props.children === undefined;
 expect(hasUndefinedChildren(JsNoChildren({})), isTrue);

@@ -54,6 +55,10 @@ main() {
expect(JsFooFunction.type, equals(_JsFooFunction));
});
});

test('with no children returns JS undefined', () {
expect(() => react_dom.render(JsNoChildren({}), Element.div()), returnsNormally);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to make sure this throws when we'd expect it to and can't result in a false positive, could we add an additional check here?

      expect(() => react_dom.render(JsNoChildren({}, jsNull), Element.div()), throws,
         reason: 'test setup check: throws when children are not undefined');

Copy link
Collaborator

@greglittlefield-wf greglittlefield-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+10

@Workiva/release-management-p

Copy link

@rmconsole-wf rmconsole-wf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 from RM

@rmconsole4-wk rmconsole4-wk merged commit e7466c7 into master Dec 6, 2022
@rmconsole4-wk rmconsole4-wk deleted the FED-202-fix-no-children-create-element branch December 6, 2022 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants