我正在构建一个实体荧光笔,以便我可以上传文本文件,查看屏幕上的内容,然后突出显示数组中的单词。这是数组由用户在手动突出显示选择时填充,例如..
const entities = ['John Smith', 'Apple', 'some other word'];
This is my text document that is displayed on the screen. It contains a lot of text, and some of this text needs to be visually highlighted to the user once they manually highlight some text, like the name John Smith, Apple and some other word
现在,我想通过将其包装在一些标记中来直观地突出显示文本中实体的所有实例,并且执行以下操作非常有效:
getFormattedText() {
const paragraphs = this.props.text.split(/\n/);
const { entities } = this.props;
return paragraphs.map((p) => {
let entityWrapped = p;
entities.forEach((text) => {
const re = new RegExp(`${text}`, 'g');
entityWrapped =
entityWrapped.replace(re, `<em>${text}</em>`);
});
return `<p>${entityWrapped}</p>`;
}).toString().replace(/<\/p>,/g, '</p>');
}
...但是(!),这只是给了我一个大字符串,所以我必须危险地设置内部 HTML,因此我不能在任何这些突出显示的实体上附加一个 onClick 事件“react方式”,这是我需要做的事情。
React 这样做的方法是返回一个看起来像这样的数组:
['This is my text document that is displayed on the screen. It contains a lot of text, and some of this text needs to be visually highlighted to the user, like the name', {}, {}, {}]
{}
包含 JSX 内容的 React 对象在哪里。
我已经用几个嵌套循环对此进行了尝试,但它有很多问题,难以阅读,并且随着我逐渐添加更多实体,性能受到了巨大打击。
所以,我的问题是......解决这个问题的最佳方法是什么?确保代码简单易读,并且我们不会遇到巨大的性能问题,因为我可能会处理很长的文档。这是我放弃我的 React 道德和危险的 SetInnerHTML 以及直接绑定到 DOM 的事件的时候吗?
更新
@AndriciCezar 在下面的回答在格式化准备好 React 渲染的字符串和对象数组方面做得很好,但是一旦实体数组很大(> 100)并且文本主体也很大(> 100kb),它的性能就不是很好. 我们正在寻找大约 10 倍的时间来将其呈现为数组 V 的字符串。
有谁知道一种更好的方法来做到这一点,它可以提高渲染大字符串的速度,但可以灵活地将 React 事件附加到元素上?或者是在这种情况下危险的SetInnerHTML 是最好的解决方案?