programing

리액트에서 HTML 코멘트를 렌더링하는 방법

lastmemo 2023. 3. 7. 21:02
반응형

리액트에서 HTML 코멘트를 렌더링하는 방법

현재 렌더 메서드는 단일 요소/구성 요소만 반환할 수 있습니다.참조: 여기

이 티켓에 대한 설명에서 일부에서는 리액트 구성 요소에서 반환된 여러 요소를 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 코멘트만을 렌더링하는 컴포넌트를 실제로 작성하려면 어떻게 해야 할까요?즉, 위의 예에서 '조각' 구성요소의 렌더링 함수는 어떻게 보일 수 있습니까?

최근 프로젝트 중 하나에서 다음과 같이 결론을 내렸습니다.

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>

다음 컴포넌트를 사용하여 실행할 수 있습니다.심플하고 기능적이지만 위험한 SetInner를 사용하기 때문에 HTML 노드(div)로 코멘트를 랩해야 하는 단점이 있습니다.HTML 속성:

    const ReactComment = ({ text }) => {
  return <div dangerouslySetInnerHTML={{ __html: `<!-- ${text} -->` }}/>
}

그런 다음 다음과 같이 사용합니다.

<ReactComment text={'My beautiful <b>HTML</b> comment'}/>

SSR와 함께 작업하기 위해 이 방법이 필요한 경우 다음과 같은 새로운 방법이 있습니다.

여기 있습니다.MaxWidthMyza라는 리액트 기반의 이메일 툴에서 사용하는 컴포넌트입니다.

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

리액트 HTML 댓글

리액트(대부분의 사람들이 이 질문에 대해 찾고 있는 것)로 코멘트를 렌더링하기 위해 저는 요지에 있는 리액트 컴포넌트를 사용합니다.Alex Zinkevych의 답변에 근거하고 있습니다만, 다음과 같이 개선되고 있습니다.

  • 소품 업데이트는 컴포넌트를 업데이트하도록 트리거하므로 코멘트가 더 역동적일 수 있습니다.
  • 컴포넌트가 그 후에 청소됩니다.
  • div는 설명 노드에 대해 스왑 아웃되기 전에 숨겨집니다.
  • (코드 스타일) React Ref 대신 사용되는ReactDOM.findDOMNode(this)React의 설명서에 따르면 이는 DOM 요소와 상호 작용하는 권장 방법입니다.

위의 GIST에 링크했습니다만, 이 글의 작성 시점에서도 내용을 카피하고 있습니다만, GIST에 버그가 발견되면 수정해, GIST에 투고합니다.

import * as React from 'react';
import * as ReactDOM from 'react-dom';

interface IProps {
    text: string;
}

export class HTMLComment extends React.Component<IProps> {
    private node: Comment;
    private ref$rootDiv = React.createRef<HTMLDivElement>();

    constructor(props: IProps) {
        super(props);

        this.node = window.document.createComment(props.text);
    }

    componentDidMount() {
        if (this.ref$rootDiv && this.ref$rootDiv.current) {
            let divElement = this.ref$rootDiv.current;

            // Tell React not to update/control this node
            ReactDOM.unmountComponentAtNode(divElement);

            // Replace the div with our comment node
            this.ref$rootDiv.current.replaceWith(this.node);
        }
    }

    componentDidUpdate(prevProps: IProps) {
        if (prevProps.text !== this.props.text) {
            this.node.textContent = this.props.text;
        }
    }

    componentWillUnmount() {
        this.node.remove();
    }

    render() {
        return (
            <div
                ref={this.ref$rootDiv}
                style={{
                    display: 'none',
                }}
            />
        );
    }
}

실제 질문에 대한 답변

그러나 OP가 Alex의 투고 코멘트에서 지적했듯이, 이것은 실제로 질문에 답하지 못한다.자녀의 전후로 코멘트를 렌더링하는 단일 컴포넌트의 경우 위에서 정의한HTMLComment 컴포넌트를 사용하여 새로운 컴포넌트를 구성할 수 있습니다.

interface IHTMLCommentWrapperProps {

}

const HTMLCommentWrapper: React.FunctionComponent<IHTMLCommentWrapperProps> = (props) => {
    return (
        <React.Fragment>
            <HTMLComment text={`<fragment data-reactid="">`} />
            {props.children}
            <HTMLComment text={`</fragment>`} />
        </React.Fragment>
    )
}

이 모든 것을 하나의 스크립트로 정리할 수 있습니다.이것은 Typescript 플레이그라운드에 있는 소스 코드와 Gist입니다(위의 컴포넌트가 크고 반복되므로 이 답변에 직접 코드를 복사하지 않습니다).

컴파일된 Javascript를 아래 스니펫에 복사할 수 있습니다.

class HTMLComment extends React.Component {
    constructor(props) {
        super(props);
        this.ref$rootDiv = React.createRef();
        this.node = window.document.createComment(props.text);
    }
    componentDidMount() {
        if (this.ref$rootDiv && this.ref$rootDiv.current) {
            let divElement = this.ref$rootDiv.current;
            // Tell React not to update/control this node
            ReactDOM.unmountComponentAtNode(divElement);
            // Replace the div with our comment node
            this.ref$rootDiv.current.replaceWith(this.node);
        }
    }
    componentDidUpdate(prevProps) {
        if (prevProps.text !== this.props.text) {
            this.node.textContent = this.props.text;
        }
    }
    componentWillUnmount() {
        this.node.remove();
    }
    render() {
        return (React.createElement("div", { ref: this.ref$rootDiv, style: {
                display: 'none',
            } }));
    }
}
const HTMLCommentWrapper = (props) => {
    return (React.createElement(React.Fragment, null,
        React.createElement(HTMLComment, { text: `<fragment data-reactid="">` }),
        props.children,
        React.createElement(HTMLComment, { text: `</fragment>` })));
};
const A = (props) => { return React.createElement("a", null, props.children); };
const B = (props) => { return React.createElement("b", null, props.children); };
const C = (props) => { return React.createElement("c", null, props.children); };
const D = (props) => { return React.createElement("d", null, props.children); };
const E = (props) => { return React.createElement("e", null, props.children); };
const App = () => {
    return (React.createElement(A, null,
        React.createElement(B, null),
        React.createElement(HTMLCommentWrapper, null,
            React.createElement(C, null),
            React.createElement(D, null)),
        React.createElement(E, null)));
};
let el$root = document.getElementById('react-app');
if (el$root) {
    ReactDOM.render(React.createElement(App, null), el$root);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="react-app"/>

이 스니펫을 실행하여 HTML을 검사하면 다음과 같은 내용이 표시됩니다.

여기에 이미지 설명 입력

에서는 ', 하다, 하다, 하다, 하다'와 구문을 을 본 이 있어요.{'<!-- comment -->'} 경우, 「」는 표시됩니다.<!-- comment --><p> ref를 'ref', '', '', 'ref'를 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref', 'ref'로 설정할 수 .ref.current.outerHTML = '<!-- comment -->'useEffect, useRef를 사용합니다.디브그래서 사용자가 코멘트를 추가했다고 생각하도록 유도하지 않는 한(페이지를 검사하고 코멘트를 표시하는 방법을 알고 있는 경우는, 송신한 React JS를 읽는 방법도 알고 있는 경우가 대부분입니다).

코멘트를 추가할 때 사용한 매우 심플하고 콤팩트한 솔루션은 다음과 같습니다.

<div style={{display:'none'}}>
    comment
</div>

검색 시 처음 착륙한 곳이기 때문에 여기에 답변을 올려야 할 필요성을 느낍니다.

, i, 、 、 、 、 html 。head 삭제:

const DangerousRawHtml = ({ html = "" }) => (
  <script dangerouslySetInnerHTML={{ __html: `</script>${html}<script>` }} />
);

사용방법:


const EmailHead = ({ title = "" }) => {
  return (
    <head>
      <title>{title}</title>
      <DangerousRawHtml html={`<!--[if !mso]><!--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]-->`} />
    </head>
  )
}

.script최적의 태그는 아니지만 동작합니다.

<html>
  <head>
    <title>Title</title>
    <script></script>
    <!--[if !mso]><!-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!--<![endif]-->
    <script></script>
  </head>
  <body></body>
</html>

만약에 음, 음, 음, 음, 음, 음, 음, 음, 음, also, also, also, also, also, also, also, also, also, also, also, also,renderToStaticMarkup해서 빈 할 수

ReactDOMServer.renderToStaticMarkup(<MyRootComponent />)
  // Remove `<DangerousRawHtml />` injected scripts
  .replace(/<script><\/script>/g, "")

React 16.8+를 사용하는 경우 텍스트 속성을 제공하고 html 주석을 렌더링할 수 있는 작은 기능 구성 요소를 사용할 수 있습니다.

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;

그러면 이렇게 사용할 수 있습니다.

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

파일명을 Comment.js로 기능 컴포넌트를 작성합니다.

jquery를 Import하여 클래스 셀렉터를 사용하여 네이티브 javascript 문서를 사용하여 div를 선택합니다.createComment

소품을 사용하여 코멘트에 사용할 텍스트와 선택할 디바의 이름을 전달합니다.

import $ from 'jquery';

const Comment = (props) => {
  const commentMakerBegin = () => {
    setTimeout(() => {
      const beginComment = document.createComment(props.beginComment);
      const firstElement = $('.' + props.beforeDiv);
      firstElement.before(beginComment);
    }, 1000);
  };

  const commentMakerEnd = (event) => {
    setTimeout(() => {
      const endComment = document.createComment(props.endComment);
      const secondElement = $('.' + props.afterDiv);
      secondElement.after(endComment);
    }, 1000);
  };
  return (
    <>
      {commentMakerBegin()}
      {props.children}
      {commentMakerEnd()}
    </>
  );
};

export default Comment;

propos.children은 커스텀 컴포넌트 태그 사이에 있는 것을 렌더링합니다.

{props.children}

"here" "Your components here"와 같은 <C /><D />'는 여는 태그와 닫는 태그 사이에 입력한 내용을 렌더링합니다.

새로 작성한 주석 컴포넌트를 사용할 컴포넌트에서 해당 컴포넌트를 Import한 후 시작 및 종료 코멘트에 사용할 소품을 통해 텍스트를 전달합니다.

다음 이미지는 두 가지 모델(각각 컨슈머 모드와 정책 모드)의 전후에 코멘트를 렌더링하는 방법입니다.

콘솔에서 코멘트가 추가된 것을 확인할 수 있습니다.

App.js 파일에서 Comments 컴포넌트를 Import하여 다음과 같이 사용합니다.그 결과 위의 스크린샷이 생성됩니다.

     <Comment
        beforeDiv='consumer-modal'
        afterDiv='policy-modal'
        beginComment='modal begins'
        endComment='modal ends'
      >
        <ConsumerModal
          title='testing'
          content={<ConsumerModalContent />}
          onClose={cnsmrModalHandler}
        ></ConsumerModal>
        <PolicyModal
          title='my policy'
          content={<PolicyModalContent />}
          onClose={policyModalHandler}
        />
      </Comment>

편집: 이 답변이 유용하다고 생각되는 사용자는 이 답변을 확인하십시오.

게시된 문제는 React에서 댓글 스타일을 요구하는 것이 아닙니다!


comment javascript를 할 수 합니다./* */

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

언급URL : https://stackoverflow.com/questions/40015336/how-to-render-a-html-comment-in-react

반응형