Reputation: 9113
Is there a way to insert an HTML comment node in React JSX, in the same way you might insert a component or DOM node?
E.g., something like:
React.createElement(Comment, {}, "comment text");
Would render to:
<!-- comment text -->
The idea is that the comment be visible on the page, so { /* this /* }
doesn't answer my question.
Note that the following related question doesn't have an answer and asks for something somewhat different:
How to render a HTML comment in React?
I just want to render a single comment node. I notice that React infrastructure renders HTML comments on its own, so perhaps there is a (slightly hacky?) way to do it too.
Upvotes: 23
Views: 8318
Reputation: 36
I experimented a lot, trying to add comments in React, and discovered this work-around — you can use a <script>
element that replaces itself with the comment. It's instant, and doesn't require a wrapper.
"use client";
export default function Comment({ text }) {
if (typeof window === "undefined") {
const code = `document.currentScript.outerHTML = "<!-- ${text} -->"`;
return <script>{code}</script>;
}
}
It happens instantly. When the browser loads the initial HTML, the script is immediately executed and replaced by a comment. If you keep reloading the page, you might see the <script>
element flash in the DevTools for just a moment.
There are no hydration errors, since by the time React loads and hydrates the document, the script element is already replaced by a comment node. The client-render of <Comment>
returns undefined
, so there isn't anything for React to match it with, and it's simply ignored.
BUT: it only works when rendered from the server-side. You may need to tinker around a bit with client-rendering part, to get the state updates working properly. Getting a reference to the comment node will probably be a bit problematic here.
Well, it should be good enough for hiding easter eggs at least!
Also, here's a IE11-friendly version that doesn't have document.currentScript
:
"use client";
import { useId } from "react";
export default function Comment({ text }) {
if (typeof window !== "undefined") return;
// eslint-disable-next-line react-hooks/rules-of-hooks
const id = useId();
const code = `document.getElementById("${id}").outerHTML = "<!-- ${text} -->"`;
return <script id={id}>{code}</script>;
}
For a renderToStaticMarkup
-compatible one (returns comments in the initial HTML, but leaves extraneous elements) see @zomars's answer under a different question.
Upvotes: 1
Reputation: 1
This solved it for me:
import {useEffect, useRef} from "react";
export const HtmlComment = (props) => {
const theRef = useRef(null)
useEffect(() => {
const comment = document.createComment(props.children);
theRef.current.replaceWith(comment);
}, []);
return (
<span ref={theRef}></span>
);
};
And then use it like this:
<HtmlComment>
Your Comment goes here
</HtmlComment>
Upvotes: 0
Reputation: 1
Yes, you can insert an HTML comment node in React JSX by using curly braces {} and JavaScript syntax. Here's an example:
import React from 'react';
const MyComponent = () => {
return (
<div>
{/* This is an HTML comment */}
<p>Some content</p>
</div>
);
};
export default MyComponent;
In the code snippet above, the HTML comment This is an HTML comment is inserted using the curly braces and the JavaScript-style comment syntax ({/* ... */}). The comment will be rendered as a regular HTML comment in the resulting HTML markup.
Please note that HTML comments are generally used for developer notes or to temporarily remove or hide parts of the code. They are not meant to be used as a way to pass data or communicate with the application logic.
Upvotes: -3
Reputation: 15587
Another alternative is to use dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{ __html: '<!-- comment text -->' }} />
dangerouslySetInnerHTML is React's replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it's dangerous.
https://facebook.github.io/react/docs/dom-elements.html#dangerouslysetinnerhtml
Upvotes: 6
Reputation: 2037
Only thing I could think of would be to manipulate the DOM on componentDidMount and add your comment there, but then React wouldn't be handling that DOM manipulation so it might cause some issues?
var HTMLComment = React.createClass({
componentDidMount: function(){
var htmlComment = "<!--" + this.props.comment + "-->";
this.span.innerHTML = htmlComment;
},
render: function(){
return (
<span ref={(span) => this.span = span} ></span>
)
}
})
Upvotes: 4