使用dangerouslySetInnerHTML

时间:2016-05-02 09:06:13

标签: reactjs react-jsx

我有一个关于使用反应的问题。正如您从标题中看到的那样,我想知道是否可以在" dangerouslySetInnerHTML"中使用React组件(由React.createClass创建)。属性。我试过了,但React打印的代码没有像这样的转换:

const MySubComponent = React.createClass({
    render() {
        return (<p>MySubComponent</p>);
    }
});

...

let myStringHTML;
myStringHTML += "<ul>";
myStringHTML += "    <li>";
myStringHTML += "        <MySubComponent />";
myStringHTML += "    </li>";
myStringHTML += "</ul>";

const MyComponent = React.createClass({
    render() {
        return (
            <div dangerouslySetInnerHTML={{__html:myStringHTML}}></div>
        );
    }
});

我期待

<ul>
    <li>
        <p>MySubComponent</p>
    </li>
</ul>

但代码与原始字符串相同,这意味着React没有转换MySubComponent。

有没有办法解决这个问题?上面的例子很简单,但我的实际代码非常复杂。非常感谢gimme一只手;)

3 个答案:

答案 0 :(得分:7)

老问题,但对于未来的知识分子,我想我可能有一个解决方案,但请注意,如果你在项目中使用它,这肯定会破坏你的redux流程。

基本上,您的id文字中应该有一些dangerousSetInnerHTML 我的想法是在将“危险的HTML”挂载到DOM之后,在id生命周期挂钩中挂载到componentDidMount

e.g。

const myStringHTML = `
  <div id="someid">
    some text in my dangerous html
  </div>
`;

const MySubComponent = React.createClass({
    render() {
        return (<p>MySubComponent</p>);
    }
});

...

let myStringHTML;
myStringHTML += "<ul>";
myStringHTML += "    <li>";
myStringHTML += "        <MySubComponent />";
myStringHTML += "    </li>";
myStringHTML += "</ul>";

const MyComponent = React.createClass({

    componentDidMount() {
      ReactDOM.render(<MyComponent />, document.querySelector('#someid'));
    }

    render() {
        return (
            <div dangerouslySetInnerHTML={{__html: myStringHTML}}></div>
        );
    }
});

请注意,不会在组件更新时调用componentDidMount。有关详细信息,请参阅lifecycle hook of react

虽然这确实感觉 hacky 但是公平警告。这也有它的限制,正如我上面提到的那些,但是有时候你 没有其他选择,只能使用dangerousSetInnerHTML,有时这样,这是一个选项。在其他时候做@Rohit Singh Sengar的建议并尝试在react中进行。

答案 1 :(得分:3)

dangerouslySetInnerHTML期望具有__html属性的JS对象应该是有效的HTML标记。相反,您在那里提供<MySubComponent />并期望它呈现该组件的HTML。 React不会在那里处理<MySubComponent />dangerouslySetInnerHTML顾名思义应该避免。此外,您在此处尝试完成的任务都可以通过React轻松完成。

const MySubComponent = React.createClass({
    render() {
        return (<li><p>MySubComponent {this.props.index}</p></li>);
    }
});

const MyComponent = React.createClass({
    render() {
        let subComponentList = [];
        [1,2,3,4,5].forEach(function(i){
            subComponentList.push(<MySubComponent key={i} index={i} />);
        }); 
        return (
            <ul>{subComponentList}</ul>
        );
    }
});

ReactDOM.render(<MyComponent />, mountNode);

答案 2 :(得分:0)

另一种方法是打开反应门户。确保元素已经渲染,然后简单地

ReactDOM.createPortal(<YourComponent>,document.querySelector('selector'));

这是到目前为止我找到的最干净的方法。