如何提取HTML字符串中的标签及内容存入数组并在React中渲染
错误原因
你调用DOMParser.parseFromString得到的是浏览器原生DOM对象,不是React支持的可渲染元素类型,因此直接传入JSX会抛出对象无法作为React子元素的报错。
可行解决方法
方案1:使用React原生dangerouslySetInnerHTML(最快实现)
这是React专门提供的渲染HTML字符串的API,代码修改如下:
<article> <h2>{blog[0].title}</h2> <p className="written-by">Written by {blog[0].author}</p> <div> {/* 替换之前的pre标签,直接渲染HTML */} <div className="pre" dangerouslySetInnerHTML={{__html: blog[0].body}} /> </div> {Cookies.get("webToken") && ( <button onClick={handleDelete}>Delete</button> )} </article>
注意:该方法存在XSS安全风险,如果博客正文是用户自由输入的内容,渲染前必须对HTML字符串做净化,过滤掉
<script>、on*事件属性等恶意内容。
方案2:第三方库渲染(更安全,无需处理XSS风险)
推荐配合dompurify(净化HTML)和html-react-parser(把HTML字符串转成React元素)使用,安全性更高,也不会用到高危API:
- 先安装依赖:
npm install dompurify html-react-parser
- 代码中引入使用:
import DOMPurify from 'dompurify'; import parse from 'html-react-parser'; // 组件内渲染部分 <article> <h2>{blog[0].title}</h2> <p className="written-by">Written by {blog[0].author}</p> <div> <div className="pre"> {parse(DOMPurify.sanitize(blog[0].body))} </div> </div> {Cookies.get("webToken") && ( <button onClick={handleDelete}>Delete</button> )} </article>
方案3:手动提取标签到数组后渲染
如果需要先把HTML的标签、属性、内容提取到数组再渲染,可以通过DOMParser遍历DOM节点生成元素数组:
const parseHtmlToArray = (htmlStr) => { const doc = new DOMParser().parseFromString(htmlStr, 'text/html'); const elements = []; // 遍历body下的所有子节点 doc.body.childNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { // 提取标签名、属性、内容,生成React元素存入数组 const attrs = {}; node.getAttributeNames().forEach(attr => { attrs[attr] = node.getAttribute(attr); }); elements.push(React.createElement(node.tagName.toLowerCase(), attrs, node.innerHTML)); } else if (node.nodeType === Node.TEXT_NODE) { elements.push(node.textContent); } }) return elements; } // 渲染时直接调用方法即可 <div className="pre">{parseHtmlToArray(blog[0].body)}</div>
内容的提问来源于stack exchange,提问作者user15499983
相关产品推荐
相关产品推荐

