2016-10-13 2 views
7

В настоящее время метод визуализации может возвращать только один элемент/компонент. См: hereКак визуализировать комментарий HTML в React?

В ходе обсуждения в рамках этого билета некоторые предлагают, чтобы обернуть несколько элементов, возвращаемых из React компонента в HTML-комментарий, чтобы компонент оберточной игнорируется браузером, например:

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

будет оказывать до:

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

Но как на самом деле создать компонент, который отображает только комментарий HTML? Другими словами, как выглядела бы функция рендеринга компонента «фрагмент» в приведенном выше примере?

+1

Лицо, опубликовавшее этот комментарий, не понимает, как работает React. Обратите внимание, что никто из тех, кто это предложил, не сработает. Во-первых, это не касается основной проблемы; результатом является четыре узла (узел комментариев, два узла элемента, а затем узел комментариев), а не один узел. –

+0

Мое понимание заключалось в том, что функция рендеринга Фрагмента вернет компонент Фрагмента с двумя дочерними компонентами «c» и «d». Поэтому закрывающий тег '/ фрагмент' во втором комментарии. Кроме того, кажется, что метод был использован для реализации компонента фрагмента в mwiencek/реакции fork в commit dcc972c414, но я мог ошибаться. – Amiramix

ответ

8

Это то, что я закончил с одним из моих недавних проектов:

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; 

Таким образом, вы можете использовать его как это:

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

Спасибо, но насколько я понимаю этот код, он не отвечает на мой вопрос. Моя цель - не давать комментарий в React, а возвращать из функции рендеринга один элемент, который отображает два комментария, один выше и один ниже его дочерних элементов. Другими словами, я должен использовать его следующим образом: '' и он должен отображать у детей два комментария, один выше и один ниже, как в примере в моем вопросе. – Amiramix

0

, как вы собираетесь это сделать вон Не работайте с простым решением для решения ванили. Однако вы можете определить пользовательский веб-компонент, который преобразуется в комментарии HTML и возвращает это из оболочки React. Примерный компонент реализован here. Для использования в реактиве см. this url.

Update 19/01/2017

Так что это непроверенные теории, но веб-компонент может быть что-то вроде -

`` `

/** 
* <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 }); 

` ``

Обратите внимание, что внутренние дети - это простой html, а не React. Однако вы можете поэкспериментировать с повышением кода до support React Components.

+0

Привет, насколько я вижу, это не сработает, так как компонент комментария должен будет отобразить два комментария, один выше и один ниже детей, переданных ему, а не отрисовка его дочерних элементов в комментарии. – Amiramix

+0

Я понимаю ваше требование от вопроса, но технически комментарий html не является элементом контейнера. Здесь у вас есть два разных комментария. Хотя в вашем примере есть тег '' и '', в результате разметки все еще четыре независимых HTML-элемента, включая компоненты 'C' и' D'. Поэтому вместо того, чтобы пытаться рассматривать два комментария как один виртуальный элемент с разными открытыми и закрывающимися тегами, рассматривайте их как братья и сестры на C и D. XHTML очень понятен в тегах контейнера, тег должен быть таким же, кроме закрывающего тега, содержащего '/'. – hazardous

+0

Я не думаю, что вы понимаете мои требования. Мое намерение состоит не в том, чтобы отображать HTML-комментарий, а для создания компонента-обертки вокруг React children, который может быть возвращен как один элемент из функции рендеринга, а 2. отображается как два комментария в HTML, один перед предоставленными детьми и другой один после оказанных детей. – Amiramix

4

Используйте фигурные скобки, чтобы вы могли использовать комментарий javascript /* */.

<a> 
    <b></b> 
    {/*<fragment data-reactid="">*/} 
     <c></c> 
     <d></d> 
    {/*</fragment>*/} 
    <e></e> 
</a> 
Смежные вопросы