【问题标题】:Replace Curly Braces in string with a HTML span Node in JSX用 JSX 中的 HTML 跨度节点替换字符串中的花括号
【发布时间】:2017-01-03 12:00:06
【问题描述】:

我有一个字符串需要参数化,例如“你好 {name},你好吗?”。我想用一个变量替换花括号和里面的文本,然后在我的 React 组件中呈现它,但我还需要通过将变量文本包装在 span/strong 标签中来突出显示和加粗该文本,例如期望的最终结果

Hello <span class="text-info"><strong>Dave</strong></span>, how are you?

我正在使用 React/JSX,我知道如何使用 String.replace 替换花括号和其中的文本,然后渲染它,例如

// This string with the placeholder curly braces would be received from an API call to a server. Only set here for demonstrative purposes
let string = 'Hello {name}, how are you?' 
let name = 'Dave' // Likewise would not be set manually here, it's held in a redux store
let greeting = string.replace(/{(.*?)}/, name);

// This renders the greeting as you'd expect e.g. <p>Hello Dave, how are you?</p>
return (
   <p>{greeting}</p>
)

但是,如果我尝试用 span 元素替换花括号,它会错误地使用 [object Object] 而不是我的参数呈现

// ...rest of stateless Component.jsx
let greeting = string.replace(/{(.*?)}/, <span>{name}</span>);

// This renders the HTML <p>Hello [object Object], how are you?</p>
return (
   <p>{greeting}</p>
)

我认为这一定与 React 逃避某些东西有关,但老实说,这完全是猜测。有什么想法可以实现所需的功能吗?

JSFiddle:https://jsfiddle.net/ExoticChimp1990/o69ymt7q/

【问题讨论】:

  • 您使用 String.replace 而不做这样的事情有什么原因吗? jsfiddle.net/e851a1ua
  • 这是因为字符串和名称变量来自服务器的单独调用。所以名称保存在用户对象的 redux 存储中。并且文本也使用占位符存储在数据库中的服务器上。所以我需要用商店的用户信息替换占位符。问题澄清
  • 转译后,&lt;span&gt;{name}&lt;/span&gt; 将被替换为返回对象的React.createElement("span", null,{name}) 的结果,这就是结果字符串显示为[object Object] 的原因。
  • @user1858268 是的,我认为可能会发生类似的事情,您知道实现所需功能的任何替代策略吗?
  • 你可以替换为"&lt;span&gt;" + {name} + "&lt;/span&gt;",然后使用setInnerHtml进行渲染。但可能还有其他方法。

标签: javascript string reactjs jsx


【解决方案1】:

您可以尝试用包含原始 html 标记的字符串替换,然后使用 dangerouslySetInnerHTML 渲染您的 div。

var greeting = textToEnhance.replace(/{(.*?)}/, '<span>'+this.props.name+'</span>'); 

return <div dangerouslySetInnerHTML={{__html:greeting}}></div>;

【讨论】:

  • 是的,我想过尝试使用危险的SetInnerHTML,但我不确定安全隐患是什么?
【解决方案2】:

顺便说一句,您可以使用 ES6 的格式,例如

const name = "David";
const myHTML = `Hello ${name}, how are you?`;

注意:这些不是单引号,而是`符号。这个符号称为“重音”字符

我了解您的模板来自服务器,因此您不能直接使用上述方法。

但是,使用诸如 /\$\{(\w+?)\}/g 之类的 RegExp(单击此 RegExp 过期),您可以解析和遍历所有变量名称,例如

var newString = templateString.replace(/(\$\{\w+?\})/g, function(match, p1, offset, str) {
  var matches = /\$\{(\w+?)\}/.exec(p1);
  var variableName = matches[1];
  return variables[variableName]
    ?variables[variableName]
    :console.error("Variable " + variableName + " is undefined in offset " + offset);
});

variables 是一个预定义的对象,其中包含您的变量作为键值对并且 templateString 包含您的模板(可选地来自服务器)。

【讨论】:

    【解决方案3】:

    您在 string.replace 中使用的第二个参数不正确。大括号内的 name 变量表示,一个 javascript 对象,其 name 键和值与 name 变量中的一样。

    let greeting = string.replace(/{(.*?)}/, '<span><strong>'+name+'</strong></span>');
    

    对不起,因为我没有输入上面的字符串作为代码,它省略了标签。现在它们必须是可见的。

    【讨论】:

    • 不,那不是真的。如果您检查小提琴,您可以看到注释掉的答案工作正常。这并不能回答我的问题,本质上是我想将变量包装在跨度标签中
    • 如果您检查来自 user1858268 的答案,您仍然需要使用危险设置的内部 HTML 来使用它
    猜你喜欢
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-09
    • 2016-04-19
    • 2011-07-17
    相关资源
    最近更新 更多