【问题标题】:Parse and Render external HTML in React component在 React 组件中解析和渲染外部 HTML
【发布时间】:2018-09-14 20:19:32
【问题描述】:

我正在编写一个基于 React 的应用程序,其中一个组件接收其 HTML 内容作为 props 中的字符串字段。此内容由 API 调用返回。

我需要:

  1. 将此内容呈现为标准 HTML(即应用样式)
  2. 解析内容以查看内容中的部分是否具有“accept-cmets”标签并在部分旁边显示“评论”按钮

例如,如果我收到下面的 HTML,我应该在 ID 为“s101”的部分旁边显示“评论”按钮。

<html>
    <head/>
    <body>
        <div id="content">
            <section id="s101" accept-comments="true">Some text that needs comments</section>
            <section id="s102">Some text that doesn't need comments</section>
        </div>
    </body>
</html>

问题:

  1. 什么是解析和呈现 HTML 的最有效方法,因为内容可能会变得有点大,有时接近 1MB?
  2. 如何确保 React 不会重新渲染该组件,因为它不会被更新?我假设总是从 shouldComponentUpdate() 返回“false”。

我尝试过的事情:

  1. 使用“dangerouslySetInnerHTML”或“react-html-parser”渲染 HTML。使用此选项,无法解析“accept-cmets”部分。
  2. 使用 DOMParser().parseFromString 解析内容。如何在 React 组件中将其输出呈现为 HTML?这对 1MB 以上的内容是否有效?

【问题讨论】:

  • 所以我假设您无法更改 API 返回的内容?
  • 确实如此。我无法更改 API 返回的内容。我需要处理它返回的 HTML 内容。
  • 好的,你已经尝试过DOMParser()。它返回一个document,这意味着您可以将其childNodes 转换为元素:codesandbox.io/s/x9vp5452z4
  • 感谢 Chris,代码 sn-p 很有帮助。我将尝试使用其中一个较大的文档并进行更新。

标签: javascript reactjs


【解决方案1】:

这个答案来自 Chris G 在 cmets 中的代码。我将代码用于不同大小的文档,效果很好。谢谢克里斯 G!

在此处发布代码以防 cmets 中的链接 link 断开。

该解决方案使用 DOMParser 解析 API 调用提供的 HTML 内容并对其进行扫描以查找应包含“评论”按钮的内容。以下是相关部分。

import React from "react";
import { render } from "react-dom";

const HTML =
  "<div><section but='yes'>Section 1</section><section>Section 2</section></div>";

class DOMTest extends React.Component {
  constructor(props) {
    super(props);

    const doc = new DOMParser().parseFromString(HTML, "application/xml");
    const htmlSections = doc.childNodes[0].childNodes;

    this.sections = Object.keys(htmlSections).map((key, i) => {
      let el = htmlSections[key];
      let contents = [<p>{el.innerHTML}</p>];

      if (el.hasAttribute("but")) contents.push(<button>Comment</button>);

      return <div key={i}>{contents}</div>;
    });
  }

  render() {
    return <div>{this.sections}</div>;
  }
}

const App = () => (
  <div>
    <DOMTest />
  </div>
);

render(<App />, document.getElementById("root"));

【讨论】:

  • 需要注意的一点是 mimetype - 可能需要指定 text/htmlapplication/xml 以便 DOM 识别预定义的 HTML 元素。
猜你喜欢
  • 2023-04-03
  • 2017-02-27
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
相关资源
最近更新 更多