Derzeit kann die Rendermethode nur ein einzelnes Element/eine einzelne Komponente zurückgeben. Siehe: hier
In der Diskussion unter diesem Ticket schlagen einige vor, mehrere Elemente, die von einer React-Komponente zurückgegeben wurden, in einen HTML-Kommentar einzuhüllen, sodass die Wrapping-Komponente vom Browser ignoriert wird, z.
<A>
<B></B>
<Fragment>
<C></C>
<D></D>
</Fragment>
<E></E>
</A>
würde machen zu:
<a>
<b></b>
<!--<fragment data-reactid="">-->
<c></c>
<d></d>
<!--</fragment>-->
<e></e>
</a>
Aber wie kann man eigentlich eine Komponente erstellen, die nur einen HTML-Kommentar darstellt? Mit anderen Worten, wie könnte die Renderfunktion der "Fragment" -Komponente im obigen Beispiel aussehen?
Damit bin ich in einem meiner letzten Projekte gelandet:
import React, {Component, PropTypes} from 'react';
import ReactDOM from 'react-dom';
class ReactComment extends Component {
static propTypes = {
text: PropTypes.string,
trim: PropTypes.bool
};
static defaultProps = {
trim: true
};
componentDidMount() {
let el = ReactDOM.findDOMNode(this);
ReactDOM.unmountComponentAtNode(el);
el.outerHTML = this.createComment();
}
createComment() {
let text = this.props.text;
if (this.props.trim) {
text = text.trim();
}
return `<!-- ${text} -->`;
}
render() {
return <div />;
}
}
export default ReactComment;
So kannst du es so benutzen:
<A>
<B></B>
<ReactComment text="<fragment>" />
<C></C>
<D></D>
<ReactComment text="</fragment>" />
<E></E>
</A>
Angenommen, Sie arbeiten mit React 16.8+), können Sie eine kleine Funktionskomponente verwenden, mit der Sie eine Texteigenschaft bereitstellen und einen HTML-Kommentar rendern können.
import React, {useEffect, useRef} from 'react';
const ReactComment = ( props ) => {
const el = useRef();
useEffect( () => {
el.current.outerHTML = `<!-- ${props.text} -->`;
}, [] );
return (
<div ref={el}/>
);
};
export default ReactComment;
Sie können es dann wie folgt verwenden
<A>
<B></B>
<ReactComment text="<fragment>" />
<C></C>
<D></D>
<ReactComment text="</fragment>" />
<E></E>
</A>
Ist hier ein anderer neuer Ansatz, wenn Sie diesen benötigen, um mit SSR zu arbeiten.
Hier ist eine MaxWidth
-Komponente, die ich mit meinem reaktionsbasierten E-Mail-Tool namens Myza verwende.
import ReactDOMServer from 'react-dom/server'
export const MaxWidth = ({ maxWidth = 0, className, children }: IMaxWidthProps) => {
const renderedChildren = ReactDOMServer.renderToStaticMarkup(
<div className={className} style={{ maxWidth: `${maxWidth}px`, margin: '0 auto' }}>
{children}
</div>
)
return <div dangerouslySetInnerHTML={{
__html: `
<!--[if mso]><center><table><tr><td width="${maxWidth}"><![endif]-->
${renderedChildren}
<!--[if mso]> </td></tr></table></center><![endif]-->
` }}
/>
}
Die Art und Weise, wie Sie dies planen, funktioniert nicht mit einer einfachen Vanilla React-Lösung. Sie können jedoch eine benutzerdefinierte Webkomponente definieren, die in HTML-Kommentare konvertiert wird, und diese aus einem React-Wrapper zurückgeben. Eine Beispielkomponente ist hier implementiert. Informationen zur Verwendung in React finden Sie unter this url .
Update 19.01.2017
Das ist also eine ungetestete Theorie, aber die Webkomponente kann so etwas sein
/**
* `<react-comment-sentinel>` Web Component
*
* @usage
```
<react-comment-sentinel sentinel="fragment">
<div>Hello there!</div>
</react-comment-sentinel>
```
* @result
```
<!-- <fragment> -->
<div>Hello there!</div>
<!-- </fragment> -->
```
*/
class CommentSentinel extends HTMLElement {
get name() {
return 'React HTML Comment';
}
createdCallback() {
/**
* Firefox fix, is="null" prevents attachedCallback
* @link https://github.com/WebReflection/document-register-element/issues/22
*/
this.is = '';
this.removeAttribute('is');
}
attachedCallback() {
const tag = this.getAttribute('sentinel');
this.outerHTML = `
<!-- <${tag}> -->
${this.innerHTML}
<!-- </${tag}> -->
`;
}
}
document.registerElement('react-comment-sentinel', CommentSentinel);
Beachten Sie, dass die inneren Kinder nur HTML sind, nicht React. Sie können jedoch auch experimentieren, indem Sie den Code um support React Components erweitern.