webentwicklung-frage-antwort-db.com.de

Wie wird ein HTML-Kommentar in React gerendert?

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?

13
Amiramix

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>
12
Alex Zinkevych

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>
1
Mat Lipe

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]-->
  ` }}
  />
}
1
briangonzalez

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.

0
hazardous