5

I have a function which returns several lines of html, like so:

render: function() {
  var badges = user.get('achievements').badges.map(function(badge) {
    var str = '<h3><span className="fa fa-fw '

    switch(badge.id) {
    case '0':
      str += ('fa-briefcase"></span><small>' + badge.text + '</small></h3>')
      break;
    case '1':
      str += ('fa-shopping-cart"></span><small>' + badge.text + '</small></h3>')
      break;
    ...
    }

    return str;
  });

  return (
    <div className="pull-right">
      {badges}
    </div>
  );
}

On doing this the string is rendered as it is on the page, as text:

<h3><span className="fa fa-fw fa-briefcase"></span><small>Visionary</small></h3><h3><span className="fa fa-fw fa-shopping-cart"></span><small>Active</small></h3><h3><span className="fa fa-fw fa-sitemap"></span><small>Lorem</small></h3><h3><span className="fa fa-fw fa-tasks"></span><small>Ipsum</small></h3><h3><span className="fa fa-fw fa-signal"></span><small>Dolor</small></h3><h3><span className="fa fa-fw fa-check-square"></span><small>Amet;</small></h3>

How do I render it as proper HTML ?

2 Answers 2

5

While using dangerouslySetInnerHTML does work, I recommend avoiding it in this case since you are in control of the markup. That attribute starts with dangerously for a reason: those badges are now a vector for code injection.

render() {
    const BADGE_ID_TO_ICON_CLASS_NAME = {
      '0': 'fa-briefcase',
      '1': 'fa-shopping-cart',
      ...
    };

    return (
      <div className="pull-right">
        {user.get('achievements').badges.map(badge => (
          <h3 key={badge.id}>
            <span
              className={`fa fa-fw ${BADGE_ID_TO_ICON_CLASS_NAME[badge.id]}`}
            />
            <small>{badge.text}</small>
          </h3>
        ))}
      </div>
    );
}
Sign up to request clarification or add additional context in comments.

6 Comments

Great answer :-) I think you meant to have the classObj values default to false, so I just flipped them.
The original code always assigned the "fa" and "fa-fw" classes, which is why they are set to true in my example. var str = '<h3><span className="fa fa-fw '
Ah, I didn't notice that. Nice :-)
Thanks for this answer. Even I felt that dangerouslySetInnerHTML was not appropriate.
You missed the closing angular bracket of span. And Stackoverflow wont allow me a single character edit :|
|
3

So I found the answer myself: We need to use dangerouslySetInnerHTML={{__html: badges} to achieve this result.

So:

<div className="pull-right" dangerouslySetInnerHTML={{__html: badges}}></div>

did the trick. Hope it helps.

1 Comment

While using dangerouslySetInnerHTML does work, I recommend avoiding it in this case since you are in control of the markup. That attribute starts with dangerously for a reason: those badges become a vector for code injection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.