最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ReactJSX Dynamic Number of Components - Stack Overflow

programmeradmin1浏览0评论

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 your renderStats without this.showBadges(stats), just have something like placeholder there and see what outputs. If that outputs it correctly, then it's probably the way you're generating the array in showBadges – A. L Commented Jun 14, 2017 at 7:06
  • @A.Lau If I use some text 123 as the placeholder, I see 123 rendered in it's place – Nyxynyx Commented Jun 14, 2017 at 7:09
  • Instead of += have you tried badgeList.push(<i>...</i>)? You're using += on an object, instead of push, 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 enclosing badgeList 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
Add a ment  | 

2 Answers 2

Reset to default 3

Change 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 />)

发布评论

评论列表(0)

  1. 暂无评论