【问题标题】:Rendering React components from an HTML string从 HTML 字符串渲染 React 组件
【发布时间】:2018-08-30 17:30:01
【问题描述】:

我从 AJAX 请求中得到一个 HTML 字符串,看起来像这样:

<div> <SpecialComponent/> <SecondSpecialComponent/></div>

我需要的是能够在 React 组件中使用这个字符串,因为它是有效的 JSX。

我尝试按照此讨论中的说明使用dangerouslySetInnerHTMLhow-to-parse-html-to-react-component

我也尝试过像 react-html-parsehtml-react-parser 这样的 React 库。没有成功

当我使用 AngularJS(1) 时,我使用了一些小指令来处理这种情况。我需要用 React 达到同样的效果。 有什么想法吗?

编辑:如果有人感兴趣,我找到了一个处理这个问题的库: https://www.npmjs.com/package/react-jsx-parser

【问题讨论】:

  • 你能把html字符串或小模板贴在这里吗,因为如果是html,使用dangerouslySetInnerHTML应该可以正常工作
  • 使用dangerouslySetInnerHTML有什么问题?
  • 您尝试执行的操作需要对内容进行转译,因为它包含jsx。这将非常困难。相反,如果您控制端点,则最好只返回可由组件呈现的 json 可序列化数据。
  • 到 Stretch0:不管我怎么尝试,它都不起作用。同样在这个例子中它不起作用:codesandbox.io/s/WnKvoY6BE。 to trixin:这会破坏我试图构建的整个想法......所以,我需要让它发挥作用:-)
  • @TomaszBubała 不,它不能正常工作。如果您检查 DOM,您将看到它没有呈现组件,而是呈现无效的 html 节点 &lt;specialcomponent&gt;。根据浏览器的不同,它可能会呈现它。但它根本不是一个反应组件。这只是因为jsx 看起来像有效的 html 标记,但实际上并非如此。

标签: javascript reactjs


【解决方案1】:

我的建议是您执行以下操作。

首先设置一个状态变量等于你要返回的 HTML

this.setState({html: response.data.html})

那么在您的退货中,您可以执行以下操作

   return ( 
   {this.state.html} 
   );

【讨论】:

  • React 转义包含 html 的字符串。这将呈现为字符串而不是标记。同样在 OPs 的情况下,标记实际上是 jsx 而不是 html。
【解决方案2】:

你不应该以这种方式做事。尽管 React 组件在使用 JSX 时看起来像 html 标签,但它们实际上不是类就是函数。您尝试做的相当于尝试解析:

"<div>document.write('foo')</div>"

您实际上是在将字符串形式的 javascript 函数名称与同一字符串中的 html 标记混合在一起。您必须解析字符串以将 React 组件与周围的 html 标记分开,将字符串形式的 React 组件映射到其实际的 React 对应项,然后使用 ReactDOM.render 将组件添加到页面。

let mapping = [
    {"name":"<SpecialComponent/><SecondSpecialComponent/>","component":<SpecialComponent/><SecondSpecialComponent/>},
    {"name":"<someOtherComponent/><someOtherComponent/>","component":<someOtherComponent/><someOtherComponent/>}
];
let markup = "<div><SpecialComponent/><SecondSpecialComponent/></div>";
let targetComponent;

mapping.forEach((obj) => {if(markup.indexOf(obj.name)>-1){
    targetComponent=obj.component;//acquired a reference to the actual component
    markup.replace(obj.name,"");//remove the component markup from the string
    }
});

/*place the empty div at the target location within the page 
give it an "id" attribute either using element.setAttribute("id","label") or 
by just modifying the string to add id="label" before the div is placed in 
the DOM ie, <div id='label'></div>*/

//finally add the component using the id assigned to it

ReactDOM.render(targetComponent,document.getElementById("label"));

以前从未尝试过。我想知道这是否真的有效:)

【讨论】:

  • 这甚至可以工作,但它非常简化。如果我正确理解 OP,他想在成熟的 CMS 系统中使用它。存在一些可以动态呈现jsx 的库,但它更适合用作交互式游乐场。 react-live 就是其中之一。
  • 说实话......我真的不明白那里发生了什么。但我知道它与这里描述的非常相似,我设法实现了:alexvab.com/posts/how-to-dynamically-render-react-js-components 这已经是一个好的开始。我可以创建一个对象来保存对我可能需要的所有相关组件的引用,然后对从服务器接收到的 HTML 字符串进行一些操作,以输出这些元素。实施起来会非常混乱,因为我可能需要传递道具。在我的 AngularJS 实现中,它只是按原样解析...
猜你喜欢
  • 2019-11-26
  • 1970-01-01
  • 2021-01-30
  • 2017-03-21
  • 2021-09-19
  • 1970-01-01
  • 2021-08-03
  • 2022-10-08
  • 2020-06-27
相关资源
最近更新 更多