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

Fix Issues with passing void elements to React with experimentalReactChildren flag set #9849

Merged
merged 6 commits into from
Feb 7, 2024

Conversation

StandardGage
Copy link
Contributor

Changes

Allows void elements such as images to be passed as children and be hydrated when using experimentalReactChildren.

should close #9833

Testing

Testing was updated to check that void elements do not have a child property and do not have dangerouslySetInnerHTML. Also updated react example to test and make showcase of the images working with a simple carousel.

Docs

https://docs.astro.build/en/guides/integrations-guide/react/#children-parsing
The docs make it seem as if this feature should already work, so I don't suppose docs would need to be updated. However, they could be updated to specifically show it working.

Copy link

changeset-bot bot commented Jan 28, 2024

🦋 Changeset detected

Latest commit: 611bed3

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added pkg: example Related to an example package (scope) pkg: react Related to React (scope) pkg: integration Related to any renderer integration (scope) labels Jan 28, 2024
@github-actions github-actions bot removed the pkg: example Related to an example package (scope) label Feb 1, 2024
}, {});
const className = innerProps.class;
delete innerProps.class;
const isVoidElement = ['img', 'input', 'br', 'hr', 'meta', 'area', 'base', 'col', 'command', 'embed', 'keygen', 'link', 'param', 'source', 'track', 'wbr'].includes(node.nodeName.toLowerCase());
Copy link
Contributor

Choose a reason for hiding this comment

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

This is perfect. On the happy path, everything will be smooth sailing. It leaves no room for the react error to appear.

However, in case the user doesn't know that react makes a distinction between normal and void elements, or if they dont know about them, it could lead to confusion. Our code would (correctly) eat up elements, but the user would just find that they silently disappeared.

I think we should be less smart here and make children undefined anytime element.childNodes has a length of 0. It might even be a lot less code for maintainers to review, which is a bonus.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've gone back to the children:undefined method and updated the tests to match this. I don't think I'm understanding when you say Our code would (correctly) eat up elements, but the user would just find that they silently disappeared. Void elements can't have children, so do we want an error to appear if you try to pass children to a void element? Or we could move that child outside of the image elements.

Copy link
Contributor

Choose a reason for hiding this comment

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

do we want an error to appear if you try to pass children to a void element?

Yes, that's the idea. Astro shouldn't be autocorrecting on behalf of the user.

Copy link
Contributor Author

@StandardGage StandardGage Feb 2, 2024

Choose a reason for hiding this comment

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

Hey I found a much simpler approach to fix the void elements. It seems to throw errors when passing children to void elements but also still renders the child as a separate element and doesn't fully break the hydration

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also is there any future thought about making the ReactChildrenFlag component based so users can decide whether to enable it based on their component's needs rather than turning it on for the whole project.

Copy link
Contributor

Choose a reason for hiding this comment

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

It hasn't come up before. Do you have just one component that needs the slotted elements to be parsed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well normally you don't need it for every react component. My specific usecase I needed it for an Image carousel component. The docs say that the flag lowers performance (although I'm not sure how much) so I figure if the flag could be changed to work like a prop where each component can decide to parse elements then that would help with performance.

@github-actions github-actions bot added feat: markdown Related to Markdown (scope) pkg: vue Related to Vue (scope) pkg: example Related to an example package (scope) 🚨 action Modifies GitHub Actions pkg: create-astro Related to the `create-astro` package (scope) pkg: astro Related to the core `astro` package (scope) pr: docs A PR that includes documentation for review labels Feb 2, 2024
@StandardGage StandardGage reopened this Feb 2, 2024
@github-actions github-actions bot removed feat: markdown Related to Markdown (scope) pkg: vue Related to Vue (scope) pkg: example Related to an example package (scope) 🚨 action Modifies GitHub Actions labels Feb 2, 2024
@github-actions github-actions bot removed pkg: create-astro Related to the `create-astro` package (scope) pkg: astro Related to the core `astro` package (scope) pr: docs A PR that includes documentation for review labels Feb 2, 2024
Copy link
Contributor

@lilnasy lilnasy left a comment

Choose a reason for hiding this comment

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

Oh wow, this is far simpler than what I thought was possible. That's genius!

Just needs a changeset that will show up in the changelog. You can create one by running pnpm -w exec changeset.

@lilnasy
Copy link
Contributor

lilnasy commented Feb 7, 2024

Sorry, I meant to ask other maintainers for review but it was the weekend and I'm just remembering.

Copy link
Member

@natemoo-re natemoo-re left a comment

Choose a reason for hiding this comment

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

Looks great, thank you!

@lilnasy
Copy link
Contributor

lilnasy commented Feb 7, 2024

Great work, @StandardGage! New codebases can be intimidating but you somehow dialed in on the perfect spot to improve it! 🎯

@lilnasy lilnasy merged commit 20ca315 into withastro:main Feb 7, 2024
13 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: integration Related to any renderer integration (scope) pkg: react Related to React (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

experimentalReactChildren flag has issues when passing Image elements
4 participants