Why can't I have a JSX comment inside an element tag? - reactjs

I'm following the common pattern of breaking multi-attribute tags on to multiple lines, eg.
<div
className="foo"
style={{ fontWeight: "bold" }}
/>
I would like to add a comment inside that declaration, eg.
<div
className="foo"
{/* This is only temporary */}
style={{ fontWeight: "bold" }}
/>
However the above syntax doesn't work; I get:
SyntaxError: Unexpected token, expected ... (45:96)
(pointing to the closing } in temporary */}.)
Is it possible to add a comment inside a tag in JSX, and if so what syntax should I use?

You can comment inside JSX tags like so:
<div
className="foo"
/* This is only temporary */
style={{ fontWeight: "bold" }}
/>
Note: there are no "{" and "}"
a live example in JSFiddle
I remember read this in the official document few years ago, but after they rewrite the document, I can't find it anymore.

The short answer is "you can't", but there are various ways to fake it. The simplest, I think, is to piggy-back on another value:
<img
alt={"settings link"
/* This is just temporary */}
src="http://www.example.com/foo.jpg"
/>
It's a bit less than optimally clear, but all we've done is moved the brace up one line. That converts the "settings link" from a HTML-esque JSX value to a Javascript expression, which just happens to have a comment.
It does have the advantage that it ties the comment to the individual attribute, rather than the tag as a whole. I think that's clearer; if you really wanted to comment on the tag you'd do better to move it to the top.
If your goal was to comment out some attribute, yeah, that's a little obscure. But it should be clear enough to un-comment when you get around to it.

I think you're confusing props and children. When you do:
<div
className="foo"
{/* bar */}
>
You are attempting to use an inline JSX expression as if you were passing props inside the opening tag, this is NOT allowed. When you have an element, the opening tag can only contain deconstructed objects or prop=value values hence the reason it expects ... to deconstruct an object with props and values, for example:
const props = {
className: "foo"
}
<div {...props}>
You can't comment inside the tag because the tag doesn't allow for inline JSX expressions. JSX expressions are only allowed as children:
{/* bar */}
<div
className="foo"
>
In this example, the expression is not inside the opening tag of an element and allowed.

Related

How to wrap JSX in parent div with shortcut in VS code

I'm buidling a React app in VS code and was was wondering if there was some sort of snippet or extension that would allow me to wrap JSX in a parent tag without having to type to opening tag then moving to the end of the piece of JSX I want to wrap in order to place the closing tag. For example I would have a bunch of paragraphs:
<p>Hi there</p>
<p>How are you?</p>
<p>More paragraphs...</p>
...
That I would want to wrap a div around so it would be like this:
<div className="some class">
<p>Hi there</p>
<p>How are you?</p>
<p>More paragraphs...</p>
......
</div>
But I find uncomfortable at times, what would have is I would type <div> then </div> would automatically show up in the same line, then I would cut it and paste it at the end of all the <p> tags. So I was wondering if there was a more efficient way of doing this?
I tried searching for extensions but could not find any.
You can do it easily.
Just select the JSX code block.
Open command palate ctrl+shift+p
Search for wrap with keyword, and then you will find something like emmet wrap with abbreviation.
Press enter after that you can write and emmet expression eg:- to wrap with div with className="some class" then you can write .some.class
if you want you can assign a shortcut to the command

How to preserve space character between replacement tags in i18next translation string

I am using v10 of react-i18next and the latest Trans component to have a translation string with a portion of the sentence bolded.
In the HTML I can insert a to ensure there is a space between the <strong> block and the rest of the sentence but it gets stripped out in the translation string.
JSX file:
<Trans i18nKey="free_trial_enabled">
<strong>30 Day Free Trial enabled</strong> for all users
</Trans>
JSON translation key/value file:
"free_trial_enabled": "<0>30 Day Free Trial enabled</0> for all users",
Output HTML:
<strong>30 Day Free Trial enabled</strong> for all users
Which looks like:
'30 Day Free Trial enabledfor all users'
How can I preserve the in the translation string so the space after the strong block will be there?
Thanks #felixmosh!
white-space: pre-wrap; fixed the issue.
I am sharing my knowledge here.
Using
white-space: pre-wrap;
Works all fine. however, in my case, I was not able to use it due to the structure of my text. I needed some text with some anchor in between. In order to get it work, I have to do the following:
"my_string": "<p><Link>Some anchor texr</Link> followed by normal text.</p>",
Then, I substitute my translatable string as follows:
<Trans
i18nKey="my_string"
components={{
Link: <a target="_blank" rel="noopener noreferrer" href={"https://some_url"}/>
}}
/>
This way works also fine in terms of adding white spaces between anchor text and normal text.
I hope this will be helpful to others as in my case, almost all of scenarios that I end up having to use i18next components are because of needing to show anchors.
Also, in case you need to be able to style your paragraph, you can make a change like this:
"my_string": "<Paragraph><Link>Some anchor texr</Link> followed by normal text.</Paragraph>",
Then, in your components declaration:
<Trans
i18nKey="my_string"
components={{
Paragraph: <p className={"my-auto"}/>,
Link: <a target="_blank" rel="noopener noreferrer" href={"https://some_url"}/>
}}
/>

Nesting variables in a React JSX string

I am modifying this code stanza
<div className={`${css['red']} ${css['blue']}`}>
...
</div>
to this, changing the blue string to a variable
var colorVariable = 'blue'
<div className={`${css['red']} ${css[{colorVariable}]}`}>
...
</div>
But this doesn't take any effect whatsoever. Neither does ${css['{colorVariable}']}.
Doing ${css[${colorVariable}]} results in a error.
What is the right way to next JSX variables in a string?
Edit:
The css object is defined as follows
import css from 'assets/style.scss'
You don't need the JSX syntax once you're already inside of the template literal.
You should be using something more along the lines of:
`${css['red']} ${css[colorVariable]}`

Inline style is not working ReactJS

I am trying to learn React. Why can you not use style inside of a return inside of a component?
The Error:
The style prop expects a mapping from style properties to values,
not a string. For example, style={{marginRight: spacing + 'em'}} when
using JSX. This DOM node was rendered by Home.
<div className="single_slide" style="background-image: url(../images/WinterCalling_2016.jpg);">
I have also tried this also:
<div className="single_slide" style={{background-image: 'url(../images/WinterCalling_2016.jpg)'}}>
or
<div className="single_slide" style={{background-image: url(../images/WinterCalling_2016.jpg)}}>
Any help with this syntax would be greatly appreciated. Other people posted they change style to say styles but that did not seem to work either.
From DOC:
In React, inline styles are not specified as a string. Instead they
are specified with an object whose key is the camelCased version of
the style name, and whose value is the style's value, usually a
string.
So instead of background-image use backgroundImage.
For example:
padding-top ---> paddingTop
padding-left ---> paddingLeft
margin-right ---> marginRight
...
How to specify the inline style?
We need to pass a object to style attribute which will contains all the values in form of key-value pair.
Like this:
<div
style={{
backgroundImage: 'url(../images/WinterCalling_2016.jpg)',
marginTop: 20}}
>
Update:
We can use template literals to pass a variable inside url, like this:
<div style={{backgroundImage: `url(${image1})`}}>
React follow the camelcase convention so you have to change background-image to backgroundImage instead.
For more info, the documentation is here.
If you want to use the style property, please provide a JavaScript dictionary object. However, the style key for background-image is backgroundImage.
<div
className="single_slide"
style={{backgroundImage: 'url(../images/WinterCalling_2016.jpg)'}}
>
Did you try wrapping background-image in quotes?
i.e.
<div className="single_slide" style={{'background-image': 'url(../images/WinterCalling_2016.jpg)'}}></div>
This seems to work for me (at least, when testing with the background-color property; I don't have an image on hand to test with for background-image)
or you can use '!important' with this ....like "background-color:red!important"
Note: And call your js in footer .Because sometimes js reacts first when we call that in header.so call your 'js' in footer.
<div class="yourclass" style="background-color:red;" >your div</div>
style="background-color:red;"

how to set the image position with JSX/HTML5?

this is a very easy question, but I can not decide what is the cleanest nor actually to get it to work. I have this JSX-part in a reactJS class, and would like to set position dynamically through a prop-value. Which tag attribute should I add to the following code snippet? I have seen examples with style and tried setting left and right etc without any success.
Any help is appreciated.
<img onClick={this.handleKeyPress} src="/image/1" alt="HTML5" width="200" height="200" />
JSX is a prepocessor syntax that will essentially create a bunch of React.createElement function calls with the right elements/components passed in to the different calls. So instead of doing React.createElement('div', props, children) for every container/component/piece of markup you want to create. The upside is that you can return component markup that's easy to read and understand but feels more familiar and easy to write than a ton of nested function calls.
There are a few key differences between regular HTML and JSX, though. Most of them stem from the clashes w/ JavaScript reserved words:
some attributes are camelCased and named slightly differently, like htmlFor (as opposed to for)
style gets passed in to the style property as an object via an outer JSX expression {{}}
most css names are different if they use a hyphen, but most just get camelCased. So: marginLeft, paddingRight, and so on
you can pass in style props just like you'd pass other props; they just go right into the style object you create for the component/element.
custom attributes (created with a hyphen) won't get rendered except for those that follow the aria spec (aria-, etc.)
So, taking that into consideration, your image component might look something like this:
<img onClick={this.handleKeyPress}
src="/image/1"
alt="HTML5"
style={{width: 200, height: 200, position: 'absolute', top: this.props.top, left: this.props.left}}/>
See also:
https://facebook.github.io/react/docs/dom-differences.html
https://facebook.github.io/react/docs/jsx-gotchas.html
Make sure you use the double curly braces on style or use a class:
<img onClick={this.handleKeyPress} src="/image/1" alt="HTML5" style={{width:"200", height:"200"}} />
<img onClick={this.handleKeyPress} src="/image/1" alt="HTML5" className="foo" />
In JSX ES6 an image needs to be imported before using it in component, or use src tag with require followed by image path within round braces all within curly braces.
you can set image property by using style tag followed by double curly braces. Don't need to give double or single inverted commas.
your image component might look something like this:
<img onClick={this.handleKeyPress} src={require("/image/1")} style={{ width: 200, height: 200 }} />
You can also use props or state value to define image properties in between style tag. Don't forgot to set state value before using this. You can set state values directly through props or through function.
This looks something like this (using through state values):
<img onClick={this.handleKeyPress} src={require("/image/1")} style={{ width: this.state.width, height: this.state.height }} />
OR
looks something like this (directly through props):
<img onClick={this.handleKeyPress} src={require("/image/1")} style={{ width: this.props.width, height: this.props.height }} />

Resources