React中的HTML和字符串的转换

问题

在使用HTML富文本编辑器控件的过程中,需要处理一些HTML字符串,将其字符串转换成DOM节点,比如用编辑器编辑了一段使用HTML标签实现的带格式的文本编辑器,然后需要在某个地方转换成DOM节点;此外还有去除HTML中标签的需求,比如说需要提取一段HTML中的纯文本内容的前N个字符作为列表页的预览之类的需求。

将字符串转换成HTML节点

原生的做法很简单,就是使用innerHTML属性就可以实现了。

1
2
3
const html = "<p>Some HTML</p>";
let div = document.getElementById('yourDOMId');
div.innerHTML = html;

上面的代码中,顺利把字符串填入了某个节点中并转换成了DOM节点。

去除字符串中的HTML标签

最直观的解决方法就是自己写正则表达式,但还有一种偷懒的方法。

1
2
3
4
const html = "<p>Some HTML</p>";
let div = document.createElement("div");
div.innerHTML = html;
const text = div.textContent || div.innerText || "";

上面的代码首先创建了一个空的div的DOM节点,然后把我们需要处理的字符串当成HTML填入其中(innerHTML属性),然后依靠textContent(标准)或者innerText(非标准)获取整个div中的文本字符串。

关于textContent和innerText的区别,一般都是说textContent是标准而innerText是非标准的,IE8就不支持textContent。

但经过试验,还是发现一点小区别(试验环境为Chrome 54)。具体不展开讨论,读者可以通过查看实时的DOM节点查看实际的效果(如下所示)。

React中将字符串转换为DOM节点

React不支持直接将字符串放到render返回值中,这样放入的字符串会被当做一般字符串处理。

1
2
3
4
5
6
7
8
const App = () => {
const str = '<div>test</div>';
return (
<div>
{str}
</div>
);
};

该组件中的str会被当做字符串处理,直接在页面中显示出来。

React有一个专门的属性叫dangerouslySetInnerHTML是用于处理这种情况的。

1
2
3
4
5
6
7
const App = () => {
const str = '<div>test</div>';
return (
<div dangerouslySetInnerHTML={str}>
</div>
);
};

像上面这种处理方式就能正确完成在React组件中渲染字符串了,不过从这个属性名就可以看出,在进行这个操作之前一定要十分清楚自己传进去的字符串是可以被转换成正确的HTML的字符串。

参考

  1. Node.textContent - MDN
  2. Node.innerText - MDN
  3. DOM Elements - React