简体   繁体   English

如何将React组件放在HTML字符串中?

[英]How to put React component inside HTML string?

I have: an array of HTML strings , eg ["<h1>Hi", "</h1>" ]. 我有: 一串HTML字符串 ,例如["<h1>Hi", "</h1>" ]。
I want to place <MyReactComponent/> in between them 我想在它们之间放置<MyReactComponent/>
(thus achieving a layout that would be in jsx: (从而实现了jsx中的布局:
<h1>Hi<MyReactComponent/></h1> ). <h1>Hi<MyReactComponent/></h1> )。

How do I achieve this? 我该如何实现这一目标?


I've tried: 我试过了:

  • Babel.transform('<h1>Hi<MyReactComponent/></h1>') (using standalone Babel). Babel.transform('<h1>Hi<MyReactComponent/></h1>') (使用独立的Babel)。 It does work, but requires me to stringify <MyReactComponent/> , which is not elegant and probably will break some day . 它确实有效,但需要我对<MyReactComponent/>进行字符串化, 这不是优雅的,可能会在某一天中断

  • to use regular jsx render() => <MyReactComponent/> , and then, on componentDidMount prepending HTML by manipulating DOM, but browser inserts closing tags automatically , so I'll be getting <h1>Hi</h1><MyReactComponent/><h1></h1> 使用常规jsx render() => <MyReactComponent/> ,然后,在componentDidMount通过操作DOM来预先添加HTML, 但是浏览器自动插入结束标记 ,所以我将获得<h1>Hi</h1><MyReactComponent/><h1></h1>

  • to use jsx-to-html library and innerHTML , to convert <MyReactComponent/> to HTML string, combine it with <h1>Hi</h1> , but it destroy any React interaction with <MyReactComponent/> . 使用jsx-to-html库和innerHTML ,将<MyReactComponent/>转换为HTML字符串,将其与<h1>Hi</h1> ,但它会破坏与<MyReactComponent/>任何React交互。

You might want to take a look at html-to-react . 你可能想看看html-to-react

This library converts the string to a node tree of DOM elements, then transforms each node to a React element using a set of instructions that you define. 此库将字符串转换为DOM元素的节点树,然后使用您定义的一组指令将每个节点转换为React元素。 I believe that it depends on the string being valid markup though, so you might have to change "<h1>Hi<MyReactComponent/></h1" to something like "<h1>Hi<x-my-react-component></x-my-react-component></h1> . 我相信它依赖于字符串是有效标记,所以你可能不得不将"<h1>Hi<MyReactComponent/></h1"更改为"<h1>Hi<x-my-react-component></x-my-react-component></h1>

Example: 例:

import { Parser, ProcessNodeDefinitions } from "html-to-react";
import MyReactComponent from "./MyReactComponent";

const customElements = {
    "x-my-react-component": MyReactComponent
};

// Boilerplate stuff
const htmlParser = new Parser(React);
const processNodeDefinitions = new ProcessNodeDefinitions(React);
function isValidNode(){
    return true;
}

// Custom instructions for processing nodes
const processingInstructions = [
    // Create instruction for custom elements
    {
        shouldProcessNode: (node) => {
            // Process the node if it matches a custom element
            return (node.name && customElements[node.name]);
        },
        processNode: (node) => {
            let CustomElement = customElements[node.name];
            return <CustomElement/>;
        }
    },
    // Default processing
    {
        shouldProcessNode: () => true,
        processNode: processNodeDefinitions.processDefaultNode
    }
];

export default class MyParentComponent extends Component {
    render () {
        let htmlString = "<h1>Hi<x-my-react-component></x-my-react-component></h1>";
        return htmlParser.parseWithInstructions(htmlString, isValidNode, processingInstructions);
    }
}

The essential part here is processingInstructions . 这里的关键部分是processingInstructions Every node in the DOM tree is checked against each instruction in the array, starting from the top, until shouldProcessNode returns true, and the node is transformed to a React element by the corresponding processNode function. DOM树中的每个节点都会根据数组中的每条指令进行检查,从顶部开始,直到shouldProcessNode返回true,并通过相应的processNode函数将节点转换为React元素。 This allows for rather complex processing rules, but it quickly gets a bit messy if you want to process nested custom elements. 这允许相当复杂的处理规则,但如果要处理嵌套的自定义元素,它会很快变得有点混乱。 The result of the example is the equivalent of 该示例的结果相当于

<h1>
    Hi
    <MyReactComponent/>
</h1>

in JSX syntax. 在JSX语法中。 Hope this helps! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM