从文本渲染React组件

时间:2017-07-12 15:00:52

标签: reactjs

我正在开发一个简单的博客/ CMS工具。在创作内容时,我支持输入原始html / css的选项。用户将此内容输入文本区域,然后我可以使用dangerouslySetInnerHtml将其呈现到页面中。这很好。

但是,我真的想在内容中嵌入一些React组件。理想情况下,我想把这样的东西输入textarea ...

<div>
  <p>Some content</p>
  <MyPictureComponent url="..." />
</div>

...然后将其渲染到页面中并让它创建MyPictureComponent。

我将存储上述&#34;代码&#34;在数据库中,并在用户查看&#34; post&#34;时动态呈现它。是否可以将原始文本渲染为功能React?

我看到这个项目(HTML to React)似乎很有希望,似乎只解析给它的HTML,而不是React组件的标签。

1 个答案:

答案 0 :(得分:1)

我找到了一种方法来做我想做的事情,但需要注意的是它有点手动,而且有潜在危险。但是,在我的情况下,我正在为非常有限的受众创建博客/ CMS,并且对用户可能插入有害内容的担忧是不存在的。

我的方法最终使用html-to-reacthttps://www.npmjs.com/package/html-to-react)。 Html-to-react接受一个字符串(包含原始HTML标记),并将其转换为适当的React组件。默认情况下,它的parse()方法无法正确处理React组件(它只是将它们转换为小写命名的html元素)。但是,库具有parseWithInstructions,它允许您控制组件中各个节点的呈现方式。

就我而言,我想启用某些React组件。其中一个是我的ExternalLink组件。接下来是我用来将一些用户输入的原始HTML转换为正确渲染我的组件的React组件的方法。

updatePreview() {

    // Combine the user-entered CSS and the user-entered HTML into a single string.
    let outputPreview = "<div><style>" + this.state.cssValue + "</style><div>" + this.state.inputValue + "</div></div>";

    let htmlToReactParser = new HtmlToReact.Parser();
    let processNodeDefinitions = new HtmlToReact.ProcessNodeDefinitions(React);
    let processingInstructions = [
        {
            // Custom <ExternalLink> processing
            shouldProcessNode: function (node) {
                return node.name === 'externallink';
            },
            processNode: function (node, children) {
                let attribs = node.attribs;
                return <ExternalLink {...attribs}>{children}</ExternalLink>
            }
        },
        {
            // Anything else
            shouldProcessNode: function (node) {
                return true;
            },
            processNode: processNodeDefinitions.processDefaultNode
        }];

    // Convert the HTML into a React component
    let reactComponent = htmlToReactParser.parseWithInstructions(outputPreview, () => true,
        processingInstructions);


    // Now that we have a react component, we set it to the state.
    // Our render() method includes a "{this.state.outputPreview}", which causes the
    // component to be rendered.
    this.setState({outputPreview: reactComponent, refreshPreviewTimer: null});
}

请注意,方法第一行中的outputString将包含一些原始文本,如下所示:

"<div>
  <style></style>
  <div>
    <p>Here's a link:<p>
    <ExternalLink url="http://www.google.com">Google</ExternalLink>
  </div>
</div>"

我将采用一些方法来更广泛地概括这种方法,使用字符串字典来支持更广泛的组件。我还将介绍一些自动导入所需组件的方法。 (目前,我手动导入所有支持的组件。)

所以,所有的功劳归于html-to-react的作者,尽管我可能会鼓励他提供一个渲染子组件的例子。