In React, is it possible to render a variable number of HTML tags or React Components?
For example, in the code below, this.renderStats()
can render 0 to 2 <i>
tags depending on the variables stats.health
and stats.energy
.
The following code prints out [object Object]
class Hero extends React.Component {
showBadges(stats) {
let badgeList = []
if (stats.health > 1000) {
badgeList += <i className="fa fa-times-circle" style={{color: "red"}}></i>
}
if (stats.energy > 100) {
badgeList += <i className="fa fa-times-circle" style={{color: "blue"}}></i>
}
return badgeList;
}
renderStats() {
return this.props.users.map((stats) => {
return (
<Td className="align-middle" column="badges">{ this.showBadges(stats) }</Td>
);
});
}
render() {
return (
<Table>
{ this.renderStats() }
</Table>
);
}
}
In React, is it possible to render a variable number of HTML tags or React Components?
For example, in the code below, this.renderStats()
can render 0 to 2 <i>
tags depending on the variables stats.health
and stats.energy
.
The following code prints out [object Object]
class Hero extends React.Component {
showBadges(stats) {
let badgeList = []
if (stats.health > 1000) {
badgeList += <i className="fa fa-times-circle" style={{color: "red"}}></i>
}
if (stats.energy > 100) {
badgeList += <i className="fa fa-times-circle" style={{color: "blue"}}></i>
}
return badgeList;
}
renderStats() {
return this.props.users.map((stats) => {
return (
<Td className="align-middle" column="badges">{ this.showBadges(stats) }</Td>
);
});
}
render() {
return (
<Table>
{ this.renderStats() }
</Table>
);
}
}
Share
Improve this question
asked Jun 14, 2017 at 7:00
NyxynyxNyxynyx
63.9k163 gold badges507 silver badges856 bronze badges
5
-
Short answer: yes, because I do it often. Why is it returning
object Object
, probably doing something wrong. Can you try rendering yourrenderStats
withoutthis.showBadges(stats)
, just have something likeplaceholder
there and see what outputs. If that outputs it correctly, then it's probably the way you're generating the array inshowBadges
– A. L Commented Jun 14, 2017 at 7:06 -
@A.Lau If I use some text
123
as the placeholder, I see123
rendered in it's place – Nyxynyx Commented Jun 14, 2017 at 7:09 -
Instead of
+=
have you triedbadgeList.push(<i>...</i>)
? You're using+=
on an object, instead ofpush
, which will give you[object Object]
. You can see this on normal javascript if you were to do that with+= {}
. I'm guessing you were looking to stringify it instead?"<i>...</i>"
– A. L Commented Jun 14, 2017 at 7:14 -
@A.Lau Using
.push
and enclosingbadgeList
with<div>
elements solved it:return ( <div> { badgeList } </div> );
– Nyxynyx Commented Jun 14, 2017 at 7:17 -
is the enclosing
<div>
necessary? doesn't feel like it should since it's returning an array. – A. L Commented Jun 14, 2017 at 7:19
2 Answers
Reset to default 3Change your showBadges
function to:
showBadges(stats) {
let badgeList = []
if (stats.health > 1000) {
badgeList.push(<i className="fa fa-times-circle" style={{color: "blue"}}></i>)
}
if (stats.energy > 100) {
badgeList.push(<i className="fa fa-times-circle" style={{color: "blue"}}></i>)
}
return badgeList;
}
And it should work.
You can either create a list of children dynamically as @Boky pointed out or take a full advantage of JSX and use inline expressions:
showBadges(stats) {
return (
<span>
{
stats.health > 1000 &&
<i className="fa fa-times-circle" style={{color: "blue"}}></i>
}
{
stats.energy > 100 &&
<i className="fa fa-times-circle" style={{color: "blue"}}></i>
}
</span>
)
}
You can use either simple boolean expression (condition && <Component />
) or ternary operator (condition ? <ComponentIfTrue /> : <ComponentIfFalse />
)