用 JSX 中的标签替换部分字符串

IT技术 reactjs react-jsx
2021-04-08 19:52:26

我正在尝试用 JSX 标签替换部分字符串,如下所示:

render: function() {
    result = this.props.text.replace(":",<div className="spacer"></div>);
    return (
         <div>        
             {result}
         <div>        
    );
}

但鉴于那this.props.textLorem : ipsum,它导致

<div>
    Lorem [object Object] ipsum.
</div>

有没有办法解决这个问题或另一种用 JSX 标签替换部分字符串的方法?

6个回答

当您将 JSX 元素replace()作为第二个参数传递给时,该元素将转换为字符串,因为replace()需要一个字符串作为第二个参数。您需要做的是将您的字符串转换为字符串和 JSX 元素的数组。所以你的result变量应该包含类似['Lorem ', <div className="spacer"></div>, ' ipsum'].

像这样的东西:

function flatMap(array, fn) {
  var result = [];
  for (var i = 0; i < array.length; i++) {
    var mapping = fn(array[i]);
    result = result.concat(mapping);
  }
  return result;
}

var Comp = React.createClass({
  render: function () {
    var result = 'Lorem : ipsum';
    result = flatMap(result.split(':'), function (part) {
      return [part, <div>spacer</div>];
    });
    // Remove the last spacer
    result.pop();
    return (
      <div>        
        {result}
      </div>
    );
  }
});
安德斯,这太棒了!你知道如果在字符串中包含(和呈现)静态 HTML,你会如何做同样的事情吗?如果 Lorem 被写入 DIV,则在 risklySetInnerHTML 中渲染 { result } 会带来各种(预期的)麻烦。
2021-05-28 19:52:26
@MagnusEngdal 接受的答案是两年前的。我今天遇到了这个问题,根据我今天所做的研究,我相信我的答案是这个问题的最佳解决方案。
2021-05-31 19:52:26

接受的答案是 5 岁。针对这个问题 issue #3368被创建,并基于一个 Facebook 员工在 React 上提供的解决方案,react-string-replace被创建。

使用 react-string-replace,这是您解决问题的方法

const reactStringReplace = require('react-string-replace');

const HighlightNumbers = React.createClass({
  render() {
    const content = 'Hey my number is 555:555:5555.';
    return (
      <span>
        {reactStringReplace(content, ':', (match, i) => (
          <div className="spacer"></div>
        ))}
      </span>
    );
  },
});
2021-05-23 19:52:26
react-string-replace是很棒的!谢谢你。
2021-05-24 19:52:26
赞成。如果“内容”实际上包含一个冒号,则可以改进该示例。或者修改 reactStringReplace 行中的匹配器以匹配内容中的其他内容。
2021-06-06 19:52:26
这个库似乎在火柴周围吃空间。
2021-06-14 19:52:26

以下也应该工作(假设 ES6),唯一的细微差别是文本实际上被包裹在一个 DIV 元素中,而不是在它前面,假设你要使用 CSS 来获得实际的间距,这应该不是问题。

const result = this.props.text.split(':').map(t => {
  return <div className='textItem'>{t}</div>;
});
我不能用像 '<span><Button act="save"/>HTML:XML</span>' 这样的字符串来做到这一点,它被 html 标签包裹
2021-05-23 19:52:26
结果将丢失间隔 div,因为您没有用任何东西替换冒号。
2021-06-11 19:52:26

为 jsx 编写了一个实用函数。

const wrapTags = (text: string, regex: RegExp, className?: string) => {
  const textArray = text.split(regex);
  return textArray.map(str => {
    if (regex.test(str)) {
      return <span className={className}>{str}</span>;
    }
    return str;
  });
};

这是黄金!但是,最好的做法是说明您的脚本实际执行的操作以及如何执行。:)
2021-06-21 19:52:26

你们正在使用复杂的方法,请保持简单:

function replaceJSX(str, find, replace) {
    let parts = str.split(find);
    for(let i = 0, result = []; i < parts.length; i++) {
        result.push(parts[i]);
        result.push(replace);
    }
    return result;
}

用法

replaceJSX(variable, ":", <br />);
这与我正在寻找的内容非常接近。但是有几个问题:这在最后添加了一个我们不想要的额外元素,并且范围result不起作用。如果在循环外返回它,则需要在循环之前声明它。这是我去的:function replaceJSX(str, find, replace) { const parts = str.split(find); const result = []; for (let i = 0; i < parts.length; i++) { result.push(parts[i]); if (i < parts.length - 1) result.push(replace); } return result; }
2021-06-10 19:52:26