How can I use comments inside the render method in a React component?
I have the following component:
'use strict';
var React = require('react'),
Button = require('./button'),
UnorderedList = require('./unordered-list');
class Dropdown extends React.Component{
constructor(props) {
super(props);
}
handleClick() {
alert('I am click here');
}
render() {
return (
<div className="dropdown">
// whenClicked is a property not an event, per se.
<Button whenClicked={this.handleClick} className="btn-default" title={this.props.title} subTitleClassName="caret"></Button>
<UnorderedList />
</div>
)
}
}
module.exports = Dropdown;
My comments are showing up in the UI.
What would be the right approach to apply single and multiple line comments inside a render method of a component?
Within the render method comments are allowed, but in order to use them within JSX, you have to wrap them in braces and use multi-line style comments.
<div className="dropdown">
{/* whenClicked is a property not an event, per se. */}
<Button whenClicked={this.handleClick} className="btn-default" title={this.props.title} subTitleClassName="caret"></Button>
<UnorderedList />
</div>
You can read more about how comments work in JSX here.
Here is another approach that allows you to use // to include comments:
return (
<div>
<div>
{
// Your comment goes in here.
}
</div>
{
// Note that comments using this style must be wrapped in curly braces!
}
</div>
);
The catch here is you cannot include a one-line comment using this approach. For example, this does not work:
{// your comment cannot be like this}
because the closing bracket } is considered to be part of the comment and is thus ignored, which throws an error.
On the other hand, the following is a valid comment, pulled directly from a working application:
render () {
return <DeleteResourceButton
// Confirm
onDelete = {this.onDelete.bind(this)}
message = "This file will be deleted from the server."
/>
}
Apparantly, when inside the angle brackets of a JSX element, the // syntax is valid, but the {/**/} is invalid. The following breaks:
render () {
return <DeleteResourceButton
{/* Confirm */}
onDelete = {this.onDelete.bind(this)}
message = "This file will be deleted from the server."
/>
}
Besides the other answers, it's also possible to use single line comments just before and after the JSX begines or ends. Here is a complete summary:
Valid
(
// this is a valid comment
<div>
...
</div>
// this is also a valid comment
/* this is also valid */
)
If we were to use comments inside the JSX rendering logic:
(
<div>
{/* <h1>Valid comment</h1> */}
</div>
)
When declaring props single line comments can be used:
(
<div
className="content" /* valid comment */
onClick={() => {}} // valid comment
>
...
</div>
)
Invalid
When using single line or multiline comments inside the JSX without wrapping them in { }, the comment will be rendered to the UI:
(
<div>
// invalid comment, renders in the UI
</div>
)
According to the official site, these are the two ways:
<div>
{/* Comment goes here */}
Hello, {name}!
</div>
Second example:
<div>
{/* It also works
for multi-line comments. */}
Hello, {name}!
</div>
Here is the reference: How can I write comments in JSX?
To summarize, JSX doesn't support comments, either html-like or js-like:
<div>
/* This will be rendered as text */
// as well as this
<!-- While this will cause compilation failure -->
</div>
and the only way to add comments "in" JSX is actually to escape into JS and comment in there:
<div>
{/* This won't be rendered */}
{// just be sure that your closing bracket is out of comment
}
</div>
if you don't want to make some nonsense like
<div style={{display:'none'}}>
actually, there are other stupid ways to add "comments"
but cluttering your DOM is not a good idea
</div>
Finally, if you do want to create a comment node via React, you have to go much fancier, check out this answer.
Two ways to add comments in React Native
// (double forward slash) is used to comment only a single line in React Native code, but it can only be used outside of the render block. If you want to comment in a render block where we use JSX, you need to use the second method.
If you want to comment on something in JSX you need to use JavaScript comments inside of curly braces like {/* Comment here /}. It is a regular / Block comment */, but it needs to be wrapped in curly braces.
Shortcut keys for /* Block comments */:
Ctrl + / on Windows and Linux.
Cmd + / on macOS.
This is how.
Valid:
...
render() {
return (
<p>
{/* This is a comment, one line */}
{// This is a block
// yoohoo
// ...
}
{/* This is a block
yoohoo
...
*/
}
</p>
)
}
...
Invalid:
...
render() {
return (
<p>
{// This is not a comment! oops! }
{//
Invalid comment
//}
</p>
)
}
...
{/*
<Header />
<Content />
<MapList />
<HelloWorld />
*/}
JSX Comments Syntax:
You can use
{/**
your comment
in multiple lines
for documentation
**/}
or
{/*
your comment
in multiple lines
*/}
for multiple lines comment.
And also,
{
//your comment
}
for single line comment.
Note: The syntax:
{ //your comment }
doesn't work. You need to type braces in new lines.
Curly braces are used to distinguish between JSX and JavaScript in a React component.
Inside curly braces, we use JavaScript comment syntax.
Reference: click here
According to React's Documentation, you can write comments in JSX like so:
One-line Comment:
<div>
{/* Comment goes here */}
Hello, {name}!
</div>
Multi-line Comments:
<div>
{/* It also works
for multi-line comments. */}
Hello, {name}!
</div>
{
// Any valid JavaScript expression
}
If you wonder why it works, it's because everything that's inside curly braces { } is a JavaScript expression.
So this is fine as well:
{ /*
Yet another JavaScript expression
*/ }
JavaScript comments in JSX get parsed as text and show up in your application.
You can’t just use HTML comments inside of JSX because it treats them as DOM nodes:
render() {
return (
<div>
<!-- This doesn't work! -->
</div>
)
}
JSX comments for single line and multiline comments follows the convention
Single line comment:
{/* A JSX comment */}
Multiline comments:
{/*
Multi
line
comment
*/}
Conditional rendering
This approach mentioned on the React docs will also work with nested /**/ comments, unlike the {/**/} approach, e.g.:
{false && <>
<div>
Commented out.
/* Anything goes. */
</div>
</>}
Full example:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello, World!</title>
<script src="https://unpkg.com/react#17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/#babel/standalone#7.14.7/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(
<div>
before
{false && <>
<div>
Commented out.
/* Anything goes. */
</div>
<div>
Also commented out.
/* Anything goes. */
</div>
</>}
after
</div>
,
document.getElementById('root')
);
</script>
</body>
</html>
renders just beforeafter.
Ah, just noticed, one downside of this is that linters like typescript could complain about stuff in the "comment" that is not correct.
Here are 6 ways of commenting in React:
Multi-line TypeScript comment
HTML Attribute comment
Single line JSX comment
Single-line JSX comment
Multi-line JSX comment
Single-line JavaScript comment
/**
* 1. Multi-line
* TypeScript comment
* #constructor
*/
export const GoodQuote = observer(({model} : { model: HomeModel }) => {
console.log(model.selectedIndex)
return useObserver(() =>
<div /* 2. HTML attribute comment */ onClick={() => model.toggleQuote()}>
<p>{model.quotes[model.selectedIndex]}</p>
{
// 3. Single-line comment
}
{ /* 4. True Single-line comment */}
{ /*
5. Multi-line
React comment
*/ }
</div> // 6. Javascript style comment
)
})
Related
In html to create a comment we use:
<!-- Write your comments here -->
What is its equivalent in React while using React components in the return section of a react component? Sometimes I just want to place some comments like
<!-- <MyComponent .... /> -->
but I can not do it in this way
You cannot do regular HTML comments in jsx, the closest you can get is JS-style comments -
{/* This is a comment */}
You have to wrap in curly braces, and then block comment: {/* <div /> */}
As mentioned in comments. You can write comments in React like below
{ /* <MyComponent .... /> */ }
Can add comment in React code on the one line
// comment
Comment in other place than is html tags for more rows
/* comments*/
But comment can add and to return part of class with {/* coments*/}. This away can get possibility write comments to more lines, like is can write comments to Java, C++, Javascript
write comments as you might do in HTML and XML with <!-- --> syntax.
will throw Unexpected token error.
To write comments in JSX, you need to use JavaScript’s forward-slash and asterisk syntax, enclosed inside a curly brace {/* comment here */}.
Here’s the example:
export default function App() {
return (
<div>
<h1>Commenting in React and JSX~ </h1>
{/* <p>My name is Bob</p> */}
<p>Nice to meet you!</p>
</div>
);
}
Ref
In React 16.2, improved support for Fragments has been added. More information can be found on React's blog post here.
We are all familiar with the following code:
render() {
return (
// Extraneous div element :(
<div>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</div>
);
}
Yes, we need a container div, but it's not that big of a deal.
In React 16.2, we can do this to avoid the surrounding container div:
render() {
return (
<Fragment>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</Fragment>
);
}
In either case, we still need need a container element surround the inner elements.
My question is, why is using a Fragment preferable? Does it help with performance? If so, why? Would love some insight.
It’s a tiny bit faster and has less memory usage (no need to create an extra DOM node). This only has a real benefit on very large and/or deep trees, but application performance often suffers from death by a thousand cuts. This is one cut less.
Some CSS mechanisms like Flexbox and CSS Grid have a special parent-child relationship, and adding divs in the middle makes it hard to keep the desired layout while extracting logical components.
The DOM inspector is less cluttered. :-)
You can find the descriptions of some other use cases in this React issue: Add fragment API to allow returning multiple components from render
Adding to all answers above there is one more advantage: code readability, Fragment component supports a syntactic sugar form, <>. Thus the code in your question can be written more easily as:
render() {
return (
<>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</>
);
}
According to docs,
In React, this desugars to a <React.Fragment/> element, as in the example from the previous section. (Non-React frameworks that use JSX may compile to something different.)
Clutter-free, right ?
Note that you still need to use <Fragment> syntax if you need to provide key to the fragment.
Added features not possible before with JSX
Better semantic jsx markup. Wrapper elements are used when needed not because they are forced to.
Less overall dom markup (increased render performance and less memory overhead)
It as simple as when you don't need a wrapper element you aren't forced to use one. Having less elements is great but I think the biggest benefit is being able to render elements in jsx that weren't previously possible and adding better semantic meaning to wrapper elements because they are optional now.
This wasn't possible before:
<select>
{this.renderOptions()}
</select>
Glancing at the following in React 15 you can't tell if the wrapper element is needed or not:
<span>
<h1>Hello</h1>
{this.getContent()}
</span>
As per the reactjs.org docs most important needs of <Fragment> </Fragment> instead of div's are to avoid breaking HTML semantics. When we use div's instead of <Fragment> </Fragment> we break the HTML semantics.
To know more about html semantics. please click
and also there are cases where if you use div's instead of Fragments it will be invalid html, for example look at this code:
class Columns extends React.Component {
render() {
return (
<div>
<td>Hello</td>
<td>World</td>
</div>
);
}
}
<table>
<tr>
<div>
<td>Hello</td>
<td>World</td>
</div>
</tr>
</table>
Fragments solve this problem.
When working with React, there are cases where you will need to render multiple elements or return a group of related items. Here’s an example:
function App() {
return (
<h1>Hello React!</h1>
<h1>Hello React Again!</h1>
);
}
If you try to run your app with the code above, you will run into an error stating that Adjacent JSX elements must be wrapped in an enclosing tag. This implies that you need to wrap both elements within a parent div.
function App() {
return (
<div>
<h1>Hello React!</h1>
<h1>Hello React Again!</h1>
</div>
);
}
Doing this will fix the error, but it comes with a degree of risk. You are adding an extra node to the DOM, which is not necessary. In a case like this, where the above is a child component that will be enclosed within a parent component, this becomes a problem.
function Table() {
return (
<table>
<td>This is a Table Component</td>
<Columns />
</table>
);
}
function Columns() {
return (
<div>
<td>Hello React!</td>
<td>Hello React Again!</td>
</div>
);
}
The resulting HTML for the Table component will be invalid because of the additional div that was added.
function Table() {
return (
<table>
<td>This is a Table Component</td>
<div>
<td>Hello React!</td>
<td>Hello React Again!</td>
</div>
</table>
);
}
Let’s take a look at a better way of solving this by using React Fragment, which will not add any additional node to the DOM. The syntax looks like this:
function Columns() {
return (
<React.Fragment>
<td>Hello React!</td>
<td>Hello React Again!</td>
</React.Fragment>
);
}
You can also use the short syntax <></> for declaring a Fragment.
function Columns() {
return (
<>
<td>Hello React!</td>
<td>Hello React Again!</td>
</>
);
}
Using <React.Fragment>...</React.Fragment>, we can add a parent tag to our JSX elements without adding an extra node to the DOM.
you can replace the extra div tags with React.Fragment
writing React.Fragment every time is too long for you. React.Fragment has a shorthand syntax that you can use. It is <>...</>.
When you want to group components but don't want a div tag HTML in the generated HTML, you can use fragment. The generated HTML for <> <p> Hello </p> </> is just this: <p> Hello </p>
If we'd have used div container, the <div>…</div> will be generated too!
(Sorry if too obvious and/or dup, couldn't find original one...)
How should I be able to comment out TodoTitle below? I tried with <!--...-->, //, /*...*/ with no luck.
class TodoApp extends React.Component {
render() {
return (
<div className="todo-app">
<TodoTitle />
</div>
);
}
}
You can comment {/* comment */} in JSX.
Can you not just use {/* stuff */} ?
I'm trying to set the inner HTML of an alert div, but receiving the error message : Can only set one of 'children' or props.dangerouslySetInnerHTML'.
Why does this happen ?
function alertContent(alert) { return {__html: alert.text} }
const Alerts = ({ alerts=[{level: 'warning', text:'<p>Warning message!</p>'}], onDismiss }) => (
<div className="alerts">
{alerts.map(alert =>
<Alert
bsStyle={alert.level}
key={alert.id}
onDismiss={onDismiss}
dangerouslySetInnerHTML={alertContent(alert)}
></Alert>
)}
</div>
)
I had this error message in a react application.
My issue was I had code as below
<p dangerouslySetInnerHTML={{ __html:stringContainingHtml}}> </p>
My issue was the space in the <p> </p> tags - since html gets injected inside these tags the space was causing an issue as it wasn't empty.
Hope this might help some people.
This happens because dangerouslySetInnerHTML can only be applied to one element. In your case, <Alert/> is a complex element made up of multiple children. That being said, the BS Alert component does accept HTML:
<Alert bsStyle="warning">
<strong>Holy guacamole!</strong> Best check yo self, you're not looking too good.
</Alert>
or
<Alert bsStyle="warning">
<span dangerouslySetInnerHTML={alertContent(alert)} />
</Alert>
Solution, You have to make a separate component to render element in which you are using dangerously set.....
For Example:
const RenderHTML = (props) => (<span dangerouslySetInnerHTML={{__html:props.HTML}}></span>)
YourData.map((d,i) => {
return <RenderHTML HTML={d.YOUR_HTML} />
})
you have to close the html tag short hand if there aren't inner HTML
<Alert dang...={} />
instead <Alert></Alert>
I have solved this issue myself.
When you are recursively rendering a component, you must separate out the part of the component where dangerouslySetInnerHTML is being used into another component and then use that component in the one you are recursively rendering.
If I have a render method in ReactJS component like this:
render: function() {
return <div>
<span>some text here</span>
</div>;
}
It ends up rendering some extra spans inside. How can I get rid of these?
It seems that any space between some block is causing this problem. For example:
<div> {foo} </div>
Will be rendered into:
<div><span/>{foo}<span/></div>
It didn't help to use parenthesis to wrap them, maybe because somewhere in my call from a parent component I am not using them.
The solution is to wrap your return in parens:
render: function() {
return (
<div>
<span>some text here</span>
</div>
);
}
Not only is it more readable but it also indicates to ReactJS to ignore the whitespace which allows you to format things as you wish.