【发布时间】:2017-10-11 11:33:47
【问题描述】:
我正在构建一个实体荧光笔,这样我就可以上传一个文本文件,查看屏幕上的内容,然后突出显示数组中的单词。这是用户在手动突出显示选择时填充的数组,例如...
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 这样做的方式是返回一个看起来像这样的数组:
['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 事件附加到元素上?或者在这种情况下,dangerouslySetInnerHTML 是最好的解决方案吗?
【问题讨论】:
-
如果您使用 Stack Snippets(
[<>]工具栏按钮)添加了一个可运行的minimal reproducible example,它会帮助人们回答这个问题,显示您想要添加文本的结构,文本来自哪里等。 Stack Snippets 支持 React,包括 JSX; here's how to do one. -
DanV,您需要更好地解决您的问题吗?也许我理解错了你问的内容?
-
嘿@AndriciCezar 你的回答看起来很棒,我只是没有时间付诸行动。谢谢顺便说一句!
-
DanV 你觉得我更新的答案怎么样?
标签: javascript reactjs jsx