React JS中无需第三方包和dangerouslySetInnerHTML实现JSON转HTML渲染
实现方案
核心思路是手动解析HTML字符串,再通过React内置的createElement方法生成对应React元素,完全不需要依赖第三方包,也不会用到dangerouslySetInnerHTML。
实现步骤
- 第一步:判断数组项是否为HTML字符串,区分普通文本和需要解析的HTML内容
- 第二步:实现轻量HTML解析逻辑,提取标签名、子内容,处理格式问题
- 第三步:把解析结果传入
createElement生成React元素,遍历渲染所有数据项
完整代码示例
import { createElement } from 'react'; // 判断是否为HTML字符串 const isHtmlString = (str) => /<[a-z][\s\S]*>/i.test(str); // 简易HTML解析器,可根据业务需求扩展支持更多标签、属性、嵌套结构 const parseHtml = (htmlStr) => { // 去除换行符和多余空白字符 const cleanedStr = htmlStr.replace(/\n/g, '').replace(/\s+/g, ' ').trim(); // 匹配外层标签 const outerTagMatch = cleanedStr.match(/^<(\w+)>(.*)<\/\1>$/); if (!outerTagMatch) return cleanedStr; const [, tagName, innerContent] = outerTagMatch; // 匹配子标签 const childTagRegex = /<(\w+)>([^<]+)<\/\1>/g; const children = []; let match; while ((match = childTagRegex.exec(innerContent)) !== null) { const [, childTag, childText] = match; // 处理示例中li文本的a)、b)前缀,匹配预期渲染效果 const formattedText = childText.trim().replace(/^[ab]\)\s*/, ''); children.push(createElement(childTag, null, formattedText)); } return createElement(tagName, null, children); }; // 渲染组件 const DataRenderer = ({ data }) => { return ( <div className="render-container"> {data.map((item, index) => ( <div key={index}> {isHtmlString(item) ? parseHtml(item) : item} </div> ))} </div> ); }; // 业务侧使用 export default function App() { const data = [ "John Doe Interests are", "<ul>\n <li>\n a) Football </li>\n <li>b) Hockey</li>\n</ul>", "Good" ]; return <DataRenderer data={data} />; }
配套CSS样式(写在全局样式文件即可):
ul { list-style: none; padding-left: 0; }
扩展说明
如果需要支持带属性的标签、多层嵌套标签等更复杂的HTML结构,只需要扩展parseHtml函数的正则匹配逻辑,增加属性提取、递归解析嵌套标签的逻辑即可,不需要引入任何第三方依赖。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

