리액트에서 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와 함께 작업하기 위해 이 방법이 필요한 경우 다음과 같은 새로운 방법이 있습니다.
여기 있습니다.MaxWidth
Myza라는 리액트 기반의 이메일 툴에서 사용하는 컴포넌트입니다.
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
'programing' 카테고리의 다른 글
Angularjs ng-model은 ng-if 내에서 동작하지 않습니다. (0) | 2023.03.07 |
---|---|
jQuery .load 응답 캐시 중지 (0) | 2023.03.07 |
$rootScope를 사용하지 않고 angular ui 라우터를 사용하여 stateChange 방지 (0) | 2023.03.07 |
외부 React에서 컴포넌트 상태 업데이트(서버 응답 시 (0) | 2023.03.07 |
브라우저:JavaScript만 사용하여 새로 고침 시 POST 데이터 재제출 방지 (0) | 2023.03.07 |