React: how to comment HTML inside a render method - reactjs

(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 */} ?

Related

Advice on Component react-ratings-declaritive

I am using a component which I have downloaded from below:
https://www.npmjs.com/package/react-ratings-declarative
It works great, but I really need the functionality to disable the component in instances where I just want to display the rating, but not have the interactive element.
I have looked through the documentation and can't find anything to disable it directly. I can see some stuff on disabling inline styles, but not sure how this would work.
I have copied the raw HTML and tried to reconstruct a component with this functionality, but there seems to be so many styles to copy, I don't think this approach would work.
Can anyone advise if this is possible or recommend an alternative component which does this?
Just don't call the method that sets state. I used the example and got rid of the changeRating method and deleted the changeRating attribute. If there is no way to change the state, users can't update the ratings.
//IMPORT STATEMENTS ETC...
class Foo extends React.Component {
constructor(props) {
super(props)
this.state = { rating: 5 }
}
/* YOU DON'T NEED THIS METHOD EITHER IF YOU'RE NOT CHANGING STATE
changeRating(rating) {
this.setState({
rating: rating
})
}
*/
render() {
return (
<div>
<Ratings
/*changeRating={this.changeRating} <-- GET RID OF THIS LINE*/
rating={this.state.rating}
widgetRatedColors='blue'>
<Ratings.Widget />
<Ratings.Widget />
<Ratings.Widget
widgetDimension='60px'
svgIconViewBox='0 0 5 5'
svgIconPath='M2 1 h1 v1 h1 v1 h-1 v1 h-1 v-1 h-1 v-1 h1 z'
/>
<Ratings.Widget widgetHoverColor='black' />
<Ratings.Widget />
</Ratings>
</div>
)
}
}
function App() {
return (
<div className='App'>
<main>
<Foo />
</main>
</div>
)
}
ReactDOM.render(<App />, document.getElementById('example'))

React component in another component

I'm beginner in React, but have to ask this question because I can't find answer
This is my code
class UserLogin extends React.Component{
render(){
const {title} = this.props
return(
<p> {title} </p>
);
}
}
class UserGuide extends React.Component{
render(){
return(
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
);
}
}
ReactDOM.render(
<UserGuide/>,
document.getElementById('app')
);
Output is
Nexicolt
not
test class
Nexicolt
Why ?
Notice that a comma after <p> is located outside JSX, so it's JavaScript syntax and not HTML text node.
Comma operator ignores the first part of an expression, <p> Test class </p>, and returns only the second part from render functon, <UserLogin title = "Nexicolt" />.
If there are multiple children elements, either an array should be returned:
return [
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
];
Or a fragment:
return <>
<p> Test class </p>
<UserLogin title = "Nexicolt" />
</>;
If you are not sure you have good uses for comma operator, ESLint no-sequences rule can be used to prevent it from being used and avoid potential mistakes.
If you are using React 16.* then you can use fragment:
return <>
<p> Test class </p>
<UserLogin title = "Nexicolt" />
</>;
or return array
return [
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
];
and if you are using React below 16 then wrap it inside div as follows:
return (
<div>
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
</div>
);
You are having Comma operator in the render function, it will only take the last part of the render function.
<p> Test class 1</p>,
<UserLogin title = "Nexicolt" />,
<p> Test class 2</p>
This will return the result 'Test class 2'.

ReactJS- Only latest line of text is appearing in web page

I have this class function
class Fact extends React.Component {
render() {
return (
<img src="Logo.png"/>,
<center><p>FACT</p></center>,
<h1>Hello</h1>
)
}
}
export default Fact;
When running my localhost server, only "Hello" appears on the webpage. The logo doesn't appear, or the text message "FACT". Only "Hello" appears...How do I fix this?
Im trying to fit in 3 paragraphs as text to appear on my website, along with the logo. What's the best practice for this, rather then spam ?
You need to wrap the render output within a "root element", such as a <div> element to ensure that reactjs renders all the contents of the Fact component as you are expecting.
See the comments and code below, showing how to correct the error:
class Fact extends React.Component {
render() {
return (
<div> {/* Add <div> opening tag here */}
<img src="Logo.png"/>,
<center><p>FACT</p></center>,
<h1>Hello</h1>
</div> {/* Add </div> closing tag here */}
)
}
}
Note also that </h1> is missing the > in your question. This has been corrected in my answer
In React, if you're rendering multiple nodes (e.g. img, center, h1), you need to nest them under one parent node, e.g. <div>. That is, you can only return one top level node from your render function.
So:
class Fact extends React.Component {
render() {
return (
<React.Fragment>
<img src="Logo.png" /> ,
<center>
<p>FACT</p>
</center>
<h1>Hello</h1>
</React.Fragment>
);
}
}
Note that React.Fragment could also be something like a div.

React conditional rendering bug even with single parent and child list [duplicate]

This question already has answers here:
How can I return multiple lines JSX in another return statement in React?
(8 answers)
Closed 4 years ago.
Learning a bit of React but it seems to me like there's a conditional rendering bug with React itself.
Suppose I have a Foo component like so:
foo.js
import React, { Component } from 'react';
class Foo extends Component {
render() {
const isLoggedIn = this.props.isLoggedIn;
return(
<div>
{ isLoggedIn ? (
<div>one</div><div>two</div>
) : (
<div>one</div><div>two</div><div>three</div>
)}
</div>
);
}
}
export default Foo;
and I use it like so:
app.js
import React, { Component } from 'react';
import Foo from './components/foo';
class App extends Component {
render() {
return (
<div>
<Foo isLoggedIn={false} />
</div>
);
}
}
export default App;
This produces the error:
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag
Please note the above Foo component, there is only a single parent div being returned not array. If it was an array, then yes I agree with the error.
The official example given in the React document's example is like this:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
https://reactjs.org/docs/conditional-rendering.html
Does this look like a bug in React to anyone?
Update
Based on the answers and comments given here, the implied behaviour of React is ternary operators inside the render() function comes with it's own render calls behind the scenes, acting like a virtual component, which would mean an extra layer of <div> needs to be wrapped around the list of my child elements.
Emberjs Foo component
My confusion arise from the fact I have done some Emberjs development in the past and a component like this works as expected:
<h3>Foo component</h3>
{{#if isLoggedIn}}
<div>one</div><div>two</div>
{{else}}
<div>one</div><div>two</div><div>three</div>
{{/if}}
Thanks for the explanation from everyone nonetheless.
You are returning the 2 or 3 divs in the condition. Instead you should wrap them into on div and return.
Notice the wrapper div below.
{ isLoggedIn ? (
<div className='wrapper'><div>one</div><div>two</div><div>
) : (
</div className='wrapper'><div>one</div><div>two</div><div>three</div></div>
)}
Also note that there is small typo below
<div>one</div><div>two</div><div>three</div
You have a syntax error
<div>one</div><div>two</div><div>three</div
should be
<div>one</div><div>two</div><div>three</div>
Did you try adding ?
return(
<div>
{ isLoggedIn ? (
<Fragment><div>one</div><div>two</div><Fragment>
) : (
<Fragment><div>one</div><div>two</div><div>three</div><Fragment>
)}
</div>
);
Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag?
you are returning multiple sibling JSX elements in an incorrect manner.
In Foo:
return(
<div>
{ isLoggedIn ? (
<div>one</div> //are siblings without
<div>two</div> //wrapping in container element.
) : (
<div>one</div> //are siblings without
<div>two</div> //wrapping in
<div>three</div>//container element.
)}
</div>
);
Right approach :
return (
<div>
{isLoggedIn
? (
<div> //add wrapper
/...
</div>
)
: (
<div> //add wrapper
//...
</div>
)}
</div>
);
Or
If you are using React16 then you can use React.Fragement as well:
e.g.
<React.Fragment>
<div>one</div>
<div>two</div>
</React.Fragment>
You need to wrap the element rendered in the condition
return(
<div>
{ isLoggedIn ? (
<div><div>one</div><div>two</div></div>
) : (
<div><div>one</div><div>two</div><div>three</div></div>
)}
</div>
);
Note the extra div around the nested conditional elements

How to use comments in React

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
)
})

Resources