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

Void Elements cannot contain Empty Fragments #13259

Closed
nmain opened this issue Jul 24, 2018 · 4 comments
Closed

Void Elements cannot contain Empty Fragments #13259

nmain opened this issue Jul 24, 2018 · 4 comments

Comments

@nmain
Copy link

nmain commented Jul 24, 2018

Do you want to request a feature or report a bug?
Not sure. Possibly either, possibly neither. I think I'm OK with the current behavior, if it's intended.

What is the current behavior?
ReactDOM throws an error when rendering a <br /> that contains an empty fragment as a child.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

https://jsfiddle.net/7f3dbpxq/

What is the expected behavior?

This might be expected. I had some code that created fragments that instead would return null when the fragment was empty, to work around #12964. When that was fixed, I removed the special case and returned empty fragments instead, which worked for me in many cases, but not this one. I think my code should better distinguish between void and regular elements, so I'm not requesting any change in React. Just posting this in case it's not desired.

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.4.1. Seems to happen in 16.0.0 as well using arrays instead of fragments: https://jsfiddle.net/6vL8ws47/

@philipp-spiess
Copy link
Contributor

Hey @nmain!

I'm curious what use case you have that needs to render fragments as children of a <br /> element. What you're seeing is React warning you from something that might be a bug on your end.

The HTML spec makes it pretty clear that <br /> elements should never have any content: https://html.spec.whatwg.org/multipage/dom.html#concept-content-nothing Although, as you said, an empty fragment is technically no content.

@nmain
Copy link
Author

nmain commented Jul 24, 2018

I have to render some very particular markup. It's XML that contains a subset of XHTML, combined with special elements, some of which contain very interactive behavior. I recursively transform those into React nodes with code that looks something like this:

function transform(x: Element) {
    const { type, props } = getTypeAndProps(x); // examines x.tagName and x.attributes to produce a React type, which is sometimes a string for the XHTML contents, and sometimes a component class for the enhanced elements, and a corresponding props object
   const children = transformChildrenRecursive(x);
    return React.createElement(type, props, React.createElement(React.Fragment, null, ...children));
}
function transformChildrenRecursive(x: Element) {
    return [...x.childNodes].map(n => n.nodeType === 1 ? transform(n) : n.textContent);
}

In the example as given here, it's simple; I would just remove the extra fragment and pass children directly to the first React.createElement call. The real thing is more complicated because there are extra layers of indirection, but the basic idea is the same.

I do accept that I should change this so that my code more explicitly calls out the fact that certain elements are void and handles them more appropriately, instead of it just "working out" by chance. I only created this bug report to see if this was behavior the React team was interested in changing.

@philipp-spiess
Copy link
Contributor

philipp-spiess commented Jul 24, 2018

Thanks for the additional information - this makes it easier to understand your needs.

I believe that your use case is very special and that you'd probably be better in fixing this by adhering to the spec and prevent empty elements from ever having children in the first place.

Adding a special case in the validation code and allowing empty fragments in void elements would create additional complexity which might not be worth it given the specific use case but I could be wrong.

@aweary
Copy link
Contributor

aweary commented Jul 24, 2018

Yeah, this is expected behavior. ReactDOM isn't meant to be a generic XML renderer. It adheres to the HTML spec and enforces behavior defined there. If you want to render arbitrary XML you can always look into using react-reconciler to create your own renderer. It's still in the early stages though, so be cautious 🙂

@aweary aweary closed this as completed Jul 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants