2016-10-13 6 views
7

Derzeit kann die Rendermethode nur ein einzelnes Element/eine einzelne Komponente zurückgeben. Siehe: hereWie Rendern eines HTML-Kommentars in React?

In der Diskussion unter diesem Ticket einige von einem Reagieren Komponente in einem HTML-Kommentar wieder mehr Elemente wickeln vorschlagen, so dass die Verpackung Komponente vom Browser ignoriert wird, zB:

<A> 
    <B></B> 
    <Fragment> 
     <C></C> 
     <D></D> 
    </Fragment> 
    <E></E> 
</A> 

machen würde zu:

<a> 
    <b></b> 
    <!--<fragment data-reactid="">--> 
     <c></c> 
     <d></d> 
    <!--</fragment>--> 
    <e></e> 
</a> 

Aber wie erstellt man tatsächlich eine Komponente, die nur HTML-Kommentar rendert? Mit anderen Worten, wie könnte die Renderfunktion der 'Fragment'-Komponente im obigen Beispiel aussehen?

+1

Die Person, die Foren, verstand nicht, wie funktioniert React. Beachten Sie, dass keiner von denen, die es vorgeschlagen haben, funktionieren würde. Zum einen geht es nicht um das Kernproblem. Das Ergebnis sind vier Knoten (ein Kommentarknoten, zwei Elementknoten und dann ein Kommentarknoten), nicht ein einzelner Knoten. –

+0

Mein Verständnis war, dass die Renderfunktion des Fragments nur die Fragmentkomponente mit zwei untergeordneten Komponenten "c" und "d" zurückgeben würde. Daher das schließende Tag '/ Fragment' im zweiten Kommentar. Es scheint auch, dass Technik verwendet wurde, um eine Fragmentkomponente in Mwiencek/React Fork in Commit dcc972c414 zu implementieren, aber ich könnte falsch liegen. – Amiramix

Antwort

8

Dies ist, was ich mit einem meiner letzten Projekte gelandet sind:

<A> 
    <B></B> 
    <ReactComment text="<fragment>" /> 
     <C></C> 
     <D></D> 
    <ReactComment text="</fragment>" /> 
    <E></E> 
</A> 
+0

Danke, aber soweit ich diesen Code verstehe, beantwortet er meine Frage nicht. Mein Ziel ist es nicht, in React einen Kommentar abzugeben, sondern von einer Renderfunktion ein einzelnes Element zurückzugeben, das zwei Kommentare abgibt, einen über und einen unter seinen Kindern. Mit anderen Worten, ich sollte es so verwenden können: ' ' und es sollte die Kinder mit zwei Kommentare, einer oben und einer unten, wie in dem Beispiel in meiner Frage. – Amiramix

0

Die Art und Weise Sie planen, diese gewonnen zu tun:

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 können Sie es wie folgt verwenden arbeite nicht mit einer Plain-Vanilla-React-Lösung. Sie können jedoch eine benutzerdefinierte Webkomponente definieren, die in HTML-Kommentare konvertiert und diese innerhalb eines React-Wrappers zurückgibt. Eine Beispielkomponente ist implementiert here. Informationen zur Verwendung in React finden Sie unter this url.

aktualisieren 19/01/2017

Das ist also nicht getestete Theorie, aber die Web-Komponente kann wie 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> --> 
*/ 
var proto = Object.create(HTMLElement.prototype, { 
name: { get: function() { return 'React HTML Comment'; } }, 
createdCallback: { value: function() { 

    /** 
    * Firefox fix, is="null" prevents attachedCallback 
    * @link https://github.com/WebReflection/document-register-element/issues/22 
    */ 
    this.is = ''; 
    this.removeAttribute('is'); 
} }, 
attachedCallback: { value: function() { 
    var tag = this.attributes("sentinel"); 
    this.outerHTML = '<!-- <' + tag + '> -->' + this.innerHtml + '<!-- </' + tag + '> -->'; 
} } 
}); 
document.registerElement('react-comment-sentinel', { prototype: proto }); 

` ``

Beachten Sie, dass die inneren Kinder einfach HTML sind, nicht Reagieren. Sie können jedoch auch experimentieren, indem Sie den Code auf support React Components erweitern.

+0

Hallo, soweit ich das sehen kann, wird das auch nicht funktionieren, da die Kommentarkomponente zwei Kommentare, einen oberhalb und einen unterhalb der untergeordneten Elemente, rendern müsste, anstatt ihre Kinder innerhalb des Kommentars zu rendern. – Amiramix

+0

Ich verstehe Ihre Anforderung von der Frage, aber technisch ein HTML-Kommentar ist kein Container-Element. Was Sie hier haben, sind zwei verschiedene Kommentare. Obwohl Ihr Beispiel "" -Tag und "" -Tag enthält, ist das resultierende Markup immer noch vier unabhängige HTML-Elemente, einschließlich der 'C'- und' D'-Komponenten. Anstatt die beiden Kommentare als ein virtuelles Element mit verschiedenen öffnenden und schließenden Tags zu betrachten, betrachten Sie sie als C- und D-Geschwister. XHTML ist bei Container-Tags sehr klar, das Tag muss identisch sein mit Ausnahme des schließenden Tags, das 'enthält/'. – hazardous

+0

Ich glaube nicht, dass Sie meine Anforderungen verstehen. Meine Absicht ist nicht, einen HTML-Kommentar zu rendern, sondern eine Wrapper-Komponente um React children zu erstellen, die 1. als ein Element von der Renderfunktion zurückgegeben werden kann und 2. als zwei Kommentare in HTML gerendert wird, eine vor den gerenderten untergeordneten Elementen und eine andere eine nach den gerenderten Kindern. – Amiramix

4

Verwenden Sie geschweifte Klammern, so dass Sie Javascript-Kommentar /* */ verwenden können.

<a> 
    <b></b> 
    {/*<fragment data-reactid="">*/} 
     <c></c> 
     <d></d> 
    {/*</fragment>*/} 
    <e></e> 
</a> 
Verwandte Themen