我正在将字符串转换为一系列图像标记,如下所示:
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'/>");
}
这会将类似{1} {G}的内容转换为
<img src='./data/img/1.png' height='20px'/><img src='./data/img/G.png' height='20px'/>
我认为路径设置正确,因为js文件存在于与'data'文件夹相同的文件夹中(我尝试使用和不使用。之前/数据)。然后,我想将此html插入到现有的&lt;李&GT;成分:
< 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>
这个“有效”,因为它向我显示原始html和图像标签,但不是我想要的实际图像。从card.manaCost周围删除{}只给我'card.manaCost'。假设我的路径是正确的,我需要做些什么才能将其解析为实际的HTML?
答案 0 :(得分:1)
如果您希望解析HTML字符串,可以使用dangerouslySetInnerHTML
属性:
<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>
然而,请注意看起来有多糟糕。这是故意的,因为React团队不希望您使用它:
innerHTML
使用不当可能会导致cross-site scripting (XSS)次攻击。消除用户输入以进行显示非常容易出错,无法正确消毒是互联网上的leading causes of web vulnerabilities之一。
我建议不要改变数组(即删除for
循环)并直接将图像创建为React元素:
<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>
答案 1 :(得分:1)
我不完全确定字符串操作对你有什么影响,也不确定你为什么需要它。
如果你正在编译JSX,那么在你的插值部分内没有理由停止它的转换。
const freeCard = (card, i) => <li key={i}>{ card.title }</li>;
const pricedCard = (card, i) => {
const src = `./data/img/${card.src}.png`;
return <li key={i}>{ card.title } <img src={ src } width="20px" /></li>;
};
render () {
<ul >
{ cards.map((card, i) => card.src ? pricedCard(card) : freeCard(card) }
</ul>
}
这应该可以正常工作。
请注意,我使用的是ES6模板字符串(用于构建src
),
和ES6箭头功能(但function freeCard (card, i) { return <li key={i}>{card.title}</li>; }
是等效的。)
如果您正在使用Babel进行转换(您应该如此),并且您正在使用足够新版本的React,那么上述内容就足够了。
唯一未展示的部分是将所有字符串操作更改为:
const parseCost = cost => cost.replace(/\{[0-z]+\}/, "$1");
cards.forEach(card => card.src = parseCost(card.manaCost));
你真正的问题是React阻止你将字符串作为HTML注入 如果你考虑为什么,它应该有意义;如果您决定创建论坛,或者添加博客评论,则React不会在默认情况下插入HTML。
您可以使用元素的dangerouslySetInnerHTML
属性,为其提供具有__html
属性的对象...
function pricedCard (card, i) {
const htmlString = "" + card.title + " <img src=\"./data/img/" + card.src + "\" />";
const content = {
__html: htmlString
};
return <li key={i} dangerouslySetInnerHTML={ content } />;
}
但是你可以看到,这可能不像你希望的那样。
就个人而言,我做的事情如下:
const FreeCard = ({ title }) => <li >{ title }</li>;
const PricedCard = ({ title, src }) => <li >{ title } <img src={ src } /></li>;
render () {
const list = cards.map((card, i) => card.src ?
<PricedCard key={i} {...card} /> :
<FreeCard key={i} {...card} />
);
return <ul>{ list }</ul>;
}
我会进一步分析我的结构<li>
,但是没有费用的卡在你的例子中没有根结构。