I've a JSX like below. The below code is Working (Multiple Ternary Conditionals).
<div className="myClassName">
{this.props.addr? this.props.addr.phoneno : '' }
{this.props.addr? (<span
className='location'>
{this.props.addr.location}
</span>) : ''}
</div>
When I tried with below Syntax with a single Ternary Operator, I'm getting Error.
<div className="myClassName">
{this.props.addr? this.props.addr.phoneno (<span
className='location'>
{this.props.addr.location}
</span>) : '' }
</div>
All I wanted is to append a Span Element with phoneno value. How to do Proper Concatenation here in this Example??
React doesn't allow returning multiple child elements inside a block. So to solve this you can use React.Fragment. There's more explanation about Fragments here.
Below is the corrected syntax.
<div className="myClassName">
{this.props.addr ? (
<React.Fragment>
{this.props.addr.phoneno}
<span className='location'>
{this.props.addr.location}
</span>
</React.Fragment>) : '' }
</div>
Related
Am trying to render different tags based JSON keys, but it keeps throwing syntax error...
adding only one of the two conditions works though !
How can I do it right ?
<ul className="features">
{
property.details.features.map((idx, feature) =>
feature.hasOwnProperty(area) ?
<li>
<span className="icon-frame"/>
<div className="english">{feature[area]}m2 </div>
</li> : null
feature.hasOwnProperty(bedRoom) ? <li>
<span className="fa fa-bed"/>
<div className="english">{feature[bedRoom]}</div>
</li> :null
)
}
</ul>
The problem is you have an arrow function without braces in the body of the function, which means the expression right after the arrow will be what that function returns. But you have two expressions in a row there (the two ternary operators), so it won't know what to return, hence the syntax error. You can try this:
<ul className="features">
{
property.details.features.map((idx, feature) =>
feature.hasOwnProperty(area) ?
(
<li>
<span className="icon-frame"/>
<div className="english">{feature[area]}m2 </div>
</li>
)
: feature.hasOwnProperty(bedRoom) ?
(
<li>
<span className="fa fa-bed"/>
<div className="english">{feature[bedRoom]}</div>
</li>
)
: null
)
}
</ul>
So, if feature has the attribute area, then render the first, else, if it has the attribute bedrom, then render the second, else, return null. I tried to make it as readable as possible but it's never easy with long ternary operators.
You can always just wrap the body of the arrow function and do it with if, else and return statements.
I'm working on creating Google amp-page in a React project, and need to fetch JSON after a click.
A/C to amp.dev, i can use amp-state to fetch remote data
as
<amp-state id="shirts" [src]="'/shirts/sizesAndPrices?sku=' + selected.sku" />
How can i do the same in JSX, as writing [src] in such format leads to error
Any suggestion will be helpful.
Thanks in advance
You can replace [src] with data-amp-bind-src. The latter syntax has been introduced for JSX syntax compatibility.
I don't know this is the right way, but I think, this can be a turn around
If there is a better way, or if this is not recommended in any way, please comment
I needed to toggle visibility of option based on the selected option
<amp-selector
layout="container"
class="radio-selector"
on="select: AMP.setState({
selectedOption: event.targetOption,
})">
<div option="a_show">Option A</div>
<div option="b_show">Option B</div>
<div option="c_show">Option C</div>
</amp-selector>
<div className="options"
dangerouslySetInnerHTML={{
__html: `
<p [class]="selectedOption == 'a_show' ? 'show' : 'hide'" class="show">a</p>
<p [class]="selectedOption == 'b_show' ? 'show' : 'hide'" class="hide">b</p>
<p [class]="selectedOption == 'c_show' ? 'show' : 'hide'" class="hide">c</p>
`
}}
/>
I have the following code in my React component's return statement:
return (
<div>
{
props.photos.length > 0 &&
<div>
{props.photos.map((photo) =>
<div>
<a target="_blank"
href="/api/game_theory/game-files/{this.props.profileId}/files/{photo.id}/{photo.downloadName}">
{photo.title}
</a>
</div>
)}
</div>
}
</div>
);
It renders without errors, however the anchor tag looks like this in the HTML:
<a target="_blank" href="/api/game_theory/game-files/{this.props.profileId}/files/{photo.id}/{photo.downloadName}">
ActualPhotoName.jpg
</a>
So photo.title is being written out correctly, but photo.id, photo.downloadName, and this.props.profileId are not.
I'm sure I'm doing something wrong and I'd appreciate any help. :)
You can't "double-interpret" javascript with brackets in JSX. Assuming your props are available to you, try using ES6 string interpolation:
href=`/api/game_theory/game-files/${this.props.profileId}/files/${photo.id}/${photo.downloadName}`>
Wrap the whole href inside { } and remove it from the props:
href={"/api/game_theory/game-files/" + this.props.profileId + "/files/" + photo.id + "/photo.downloadName"}
I have this as my render function and I'm trying to pass the "{this.state.poster}" through it so it will load what ever random film poster it has received from the api. the console.log will show as /q2Y2EuDSaNCH88ETlyiu8bZc5TT.jpg for example but when I try to add that to the image with {this.state.poster} it doesn't work and im not sure why.
render() {
console.log(this.state.poster);
return (
<div className="main">
<h1> Lets see what you got</h1>
<div name="title">
{this.state.title}
</div>
<div name="overview">
{this.state.overview}
</div>
<div name="poster_path">
<img src="https://image.tmdb.org/t/p/original/${this.state.poster}" alt="picture" />
</div>
<div name="vote_average">
Vote:{this.state.vote}
</div>
<button onClick={this.getFilm}>Get Random Movie</button>
</div>
);
}
}
export default App;
first the curly brace specifying a js expression then string interpolation :)
<img src={`https://image.tmdb.org/t/p/original/${this.state.poster}`} alt="picture" />
string interpolation only works inside js expressions ;).
The ${expression} syntax is meant to be used in template literals
What you want here is to concatenate the state with the beginning of the image url like this :
<img
src={'https://image.tmdb.org/t/p/original/' + this.state.poster}
alt="picture"
/>
or by using a method like
getImgUrl (image) {
return 'https://image.tmdb.org/t/p/original/' + image;
}
and using it with
<img
src={this.getImgUrl(this.state.poster)}
alt="picture"
/>
You say that console.log prints out /q2Y2EuDSaNCH88ETlyiu8bZc5TT.jpg.
There is a backslash as the first character.
That tells me that the src attribute's value will be https://image.tmdb.org/t/p/original//q2Y2EuDSaNCH88ETlyiu8bZc5TT.jpg.
Note, the // to the right of original.
Try removing the extra backslash like following:
https://image.tmdb.org/t/p/original${this.state.poster}
In my react classes, I often find myself having to use conditional logic to decide what to render. The problem with such an approach is that it leads to a lot of redundant markup. Here is an example:
if(this.props.quotes) {
return (
<div className="card">
<div className="item-1">{this.props.header}</div>
<div className="item-2">Add content...</div>
<i className="fa fa-quote-left"></i>
<i className="fa fa-quote-right"></i>
</div>
);
}
else {
return (
<div className="card">
<div className="item-1">{this.props.header}</div>
<div className="item-2">Add content...</div>
</div>
);
}
The only difference between the two HTML components is that one has two extra font-awesome elements. Ideally, you would want to use some base markup, and append content to it based on the result of the conditional.
I tried the following approach where I put the HTML content into an array and pushed the extra HTML elements in if the condition this.props.quotes was met:
var cardContent = [
<div className="item-1">{this.props.header}</div>,
<div className="item-2">Add content...</div>
];
if(this.props.quotes) {
cardContent.push(<i className="fa fa-quote-left"></i>);
cardContent.push(<i className="fa fa-quote-right"></i>);
}
return (
<div className="card">
{cardContent}
</div>
);
This introduces a new problem, mainly that React complains about missing key props in the array:
Warning: Each child in an array or iterator should have a unique "key" prop.
In this context, it doesn't make sense to give the elements keys since 3/4 of the content is static (the only non-static element is {this.props.header}).
Is there a better way of appending to existing JSX than the method I outlined above? I don't want to suppress all unique key prop warnings since it is still valid in the case of mapping. Is it better to just accept the redundant HTML approach?
When you render an Array of JSX elements, each one must have a key property on them. As you construct your array, you can do something like
cardContent.push(<div className="item-1" key="item-1">..</div>)
cardContent.push(<div className="item-2" key="item-2">..</div>)
I also want to mention for the example you've described, your elements are simple enough that having an inline condition rather than having two blocks that you conditionally return
return (
<div className="card">
<div className="item-1">{this.props.header}</div>
<div className="item-2">Add content...</div>
{this.props.quotes && <i className="fa fa-quote-left"></i>}
{this.props.quotes && <i className="fa fa-quote-right"></i>}
</div>
)