Ad

Passing Html Components As A Parameter Property Into
  • Tags With React.js
  • - 1 answer

    I'm transforming a string into a series of image tags as follows:

    for (var i = 0; i < cardCollection.length; i++) {
      cardCollection[i].manaCost = cardCollection[i].manaCost.replace(/\{([0-z]+)\}/g, "<img src='\\data\\img\\$1.png' height='20px'/>");
    }

    This transforms something like {1}{G} into

    <img src='./data/img/1.png' height='20px'/><img src='./data/img/G.png' height='20px'/>

    I presume the path is set correctly since the js file this is in lives in the same folder as the 'data' folder (and I've tried with and without the . before /data). I then want to insert this html into an existing < li> component:

    < ul onClick = {this.handleListClick} > 
    { cardCollection.map(function(card) {
        if (card.manaCost != undefined) {
            return <li>{card.name} {card.manaCost} </li>; 
        }
        else {
            return <li>{card.name}</li > ;
        }
      })
    } < /ul>

    This 'works' in that it shows me the raw html and the image tags, but not the actual images I'm trying to get. Removing the {} from around card.manaCost just gives me 'card.manaCost'. Assuming my path is correct, what do I have to do to get it to parse it as actual HTML?

    Ad

    Answer

    If you want your HTML string to be parsed, you can use the dangerouslySetInnerHTML property:

    <ul onClick = {this.handleListClick}> 
    { cardCollection.map(function(card) {
        if (card.manaCost != undefined) {
            var html = card.name + ' ' + card.manaCost;
            return <li dangerouslySetInnerHTML={{__html: html}} />;
        }
        else {
            return <li>{card.name}</li>;
        }
      })
    } </ul>
    

    However, notice how bad that looks. This is intentional, because the React team doesn't want you to use it:

    Improper use of the innerHTML can open you up to a cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly/Cross-site_scripting" >cross-site scripting (XSS) attack. Sanitizing user input for display is notoriously error-prone, and failure to properly sanitize is one of the leading causes of web vulnerabilities on the internet.

    I recommend not mutating the array (i.e. removing that for loop) and creating images as React elements directly:

    <ul onClick = {this.handleListClick}> 
    { cardCollection.map(function(card, i) {
        var manaCost;
        if (card.manaCost) {
          manaCost = card.manaCost
            .match(/\{[0-z]+\}/g)
            .map(function (basename, i) {
              var src = './data/img/' + basename.substring(1, basename.length - 1) + '.png';
              return <img key={i} src={src} height='20px' />;
            });
        }
        return <li key={i}>{card.name} {manaCost}</li>;
      })
    } </ul>
    
    Ad
    source: stackoverflow.com
    Ad