如何解析html到React组件?

时间:2017-06-20 03:37:33

标签: javascript html reactjs compilation content-management-system

这是我的晚宴:
1.申请请求CMS(内容管理系统)页面内容 2. CMS返回"<div>Hi,<SpecialButton color="red">My Button</SpecialButton></div>"
3.应用程序使用内容,使用属性中提供的数据呈现相应的组件。

我无法弄清楚如何以React方式执行第3步,任何建议都表示赞赏。

感谢@Glenn Reyes,这里有Sandbox来说明问题。

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

const SpecialButton = ({ children, color }) => (
  <button style={{color}}>{children}</button>
);

const htmlFromCMS = `
<div>Hi, 
  <SpecialButton color="red">My Button</SpecialButton>
</div>`;

const App = () => (
  <div dangerouslySetInnerHTML={{__html: htmlFromCMS}}>
  </div>
);

// expect to be same as
// const App = () => (
//   <div>Hi, 
//     <SpecialButton color="red">My Button</SpecialButton>
//   </div>
// );

render(<App />, document.getElementById('root'));
Vuejs提出的{p> Here is a live demo。字符串"<div v-demo-widget></div>"可以视为Vuejs指令并呈现。 Source Code

5 个答案:

答案 0 :(得分:15)

您可能希望深入了解dangerouslySetInnerHTML。以下是如何从React组件中的字符串呈现HTML的示例:

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

const htmlString = '<h1>Hello World! </h1>';

const App = () => (
  <div dangerouslySetInnerHTML={{ __html: htmlString }} />
);

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

此处的完整示例:https://codesandbox.io/s/xv40xXQzE

在此处的React文档中详细了解dangerouslySetInnerHTMLhttps://facebook.github.io/react/docs/dom-elements.html#dangerouslysetinnerhtml

答案 1 :(得分:2)

如果您不想使用react-html-parser属性,可以使用dangerouslySetInnerHTML

import React from 'react';
import { render } from 'react-dom';
import ReactHtmlParser from 'react-html-parser';

const SpecialButton = ({ children, color }) => (
  <button style={{color}}>{children}</button>
);

const htmlFromCMS = `
<div>Hi, 
  <SpecialButton color="red">My Button</SpecialButton>
</div>`;

const App = () => (
  <div>
     {ReactHtmlParser(htmlFromCMS)}
  </div>
);


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

快乐编码!

答案 2 :(得分:2)

正如 EsterlingAccimeYoutuber 在 this 回答中指出的那样,如果您不想使用 parser 属性,可以使用 dangerouslySetInnerHTML

到现在为止,react-html-parser 已经 3 年没有更新了,所以我去找了一个不同的模块。

html-react-parser 做同样的工作,但经常维护和更新。

清理您的 html-String 以防止 XSS 攻击应该是一种很好的做法。 dompurify 可用于此目的。

我将 EsterlingAccimeYoutuber 的代码示例更新为以下内容:

import React from 'react';
import { render } from 'react-dom';
import parse from 'html-react-parser';
import DOMPurify from 'dompurify';

const SpecialButton = ({ children, color }) => (
  <button style={{color}}>{children}</button>
);

const htmlFromCMS = `
<div>Hi, 
  <SpecialButton color="red">My Button</SpecialButton>
</div>`;

const htmlFrom = (htmlString) => {
        const cleanHtmlString = DOMPurify.sanitize(htmlString,
          { USE_PROFILES: { html: true } });
        const html = parse(cleanHtmlString);
        return html;
}

const App = () => (
  <div>
     {htmlFromCMS && htmlFrom(htmlFromCMS)}
  </div>
);


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

灵感来自上面的原始帖子,因此特别感谢原作者!

答案 3 :(得分:1)

您可以尝试使用ReactDOMservervar count = $('#divPhoto').children().length; // You'll get the length in this. 呈现到服务器上的<MyReactComponent />,然后将其传递到客户端,您可以通过{{{} {{{ 3}}

答案 4 :(得分:1)

对于任何来自未来只是增强GProst的答案,你可以使用ReactDOMserver,这就是我们如何实现它。

public void actionPerformed(ActionEvent e) {
    if(e.getSource()==tab[0][0] && mine[0][0]==9) {
        tab[0][0].setText("B");
        tab[0][0].setEnabled(false);
    }
    if(e.getSource()==tab[0][1] && mine[0][1]==9) {
        tab[0][1].setText("B");
        tab[0][1].setEnabled(false);
    }
    if(e.getSource()==tab[0][2] && mine[0][2]==9) {
        tab[0][2].setText("B");
        tab[0][2].setEnabled(false);
    }