使用ReactJS突出显示文本

And*_*unt 16 javascript reactjs react-jsx

我正在尝试突出显示与查询匹配的文本,但我无法弄清楚如何使标记显示为HTML而不是文本.

var Component = React.createClass({
    _highlightQuery: function(name, query) {
        var regex = new RegExp("(" + query + ")", "gi");
        return name.replace(regex, "<strong>$1</strong>");
    },
    render: function() {
        var name = "Javascript";
        var query = "java"
        return (
            <div>
                <input type="checkbox" /> {this._highlightQuery(name, query)}
            </div>
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

当前输出:<strong> Java </ strong>脚本

期望的输出:Java脚本

pet*_*tos 42

这是我简单的twoliner辅助方法:

getHighlightedText(text, higlight) {
    // Split text on higlight term, include term itself into parts, ignore case
    var parts = text.split(new RegExp(`(${higlight})`, 'gi'));
    return <span>{parts.map(part => part.toLowerCase() === higlight.toLowerCase() ? <b>{part}</b> : part)}</span>;
}
Run Code Online (Sandbox Code Playgroud)

它返回一个span,其中所请求的部分与<b> </b>标签一起高亮显示.如果需要,可以简单地修改它以使用其他标记.

更新:为了避免唯一密钥丢失警告,这里是一个基于跨度和设置fontWeight样式的解决方案匹配部件:

getHighlightedText(text, higlight) {
    // Split on higlight term and include term into parts, ignore case
    let parts = text.split(new RegExp(`(${higlight})`, 'gi'));
    return <span> { parts.map((part, i) => 
        <span key={i} style={part.toLowerCase() === higlight.toLowerCase() ? { fontWeight: 'bold' } : {} }>
            { part }
        </span>)
    } </span>;
}
Run Code Online (Sandbox Code Playgroud)

  • 我想指出一点。我很困惑为什么他的“零件”仍然包含分隔符。考虑一下,string.split()始终排除分隔符。事实证明,有一个特例是.split(regex)(正则表达式具有捕获组)也会将捕获的元素插入到结果数组中。这是有关这种超级随机边缘情况的官方文档的链接:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split。向下滚动到“使用RegExp分割以将分隔符的一部分包括在结果中” (2认同)

Hen*_*k T 18

下面是一个使用标准<mark>标签突出显示文本的 react 组件示例:

const Highlighted = ({text = '', highlight = ''}) => {
   if (!highlight.trim()) {
     return <span>{text}</span>
   }
   const regex = new RegExp(`(${_.escapeRegExp(highlight)})`, 'gi')
   const parts = text.split(regex)
   return (
     <span>
        {parts.filter(part => part).map((part, i) => (
            regex.test(part) ? <mark key={i}>{part}</mark> : <span key={i}>{part}</span>
        ))}
    </span>
   )
}
Run Code Online (Sandbox Code Playgroud)

这是如何使用它

<Highlighted text="the quick brown fox jumps over the lazy dog" highlight="fox"/>
Run Code Online (Sandbox Code Playgroud)

  • 完美解决方案! (2认同)
  • 请注意,这使用了 lodash `_.escapeRegExp` (2认同)

Yoa*_*osh 8

这是我的解决方案。

我试图专注于简单性和性能,因此我避免了涉及在 React 之外手动操作 DOM 的解决方案,或者像dangerouslySetInnerHTML.

此外,该解决方案负责将后续匹配合并为单个<span/>,从而避免出现冗余跨度。

const Highlighter = ({children, highlight}) => {
  if (!highlight) return children;
  const regexp = new RegExp(highlight, 'g');
  const matches = children.match(regexp);
  console.log(matches, parts);
  var parts = children.split(new RegExp(`${highlight.replace()}`, 'g'));

  for (var i = 0; i < parts.length; i++) {
    if (i !== parts.length - 1) {
      let match = matches[i];
      // While the next part is an empty string, merge the corresponding match with the current
      // match into a single <span/> to avoid consequent spans with nothing between them.
      while(parts[i + 1] === '') {
        match += matches[++i];
      }

      parts[i] = (
        <React.Fragment key={i}>
          {parts[i]}<span className="highlighted">{match}</span>
        </React.Fragment>
      );
    }
  }
  return <div className="highlighter">{parts}</div>;
};
Run Code Online (Sandbox Code Playgroud)

用法:

<Highlighter highlight='text'>Some text to be highlighted</Highlighter>
Run Code Online (Sandbox Code Playgroud)

查看此codepen的实例。


aij*_*aij 6

NPM上已经有一个React组件可以执行您想要的操作:

var Highlight = require('react-highlighter');
[...]
<Highlight search={regex}>{name}</Highlight>
Run Code Online (Sandbox Code Playgroud)