2016-08-26 26 views
2

我是React新手,不确定处理以下情况的正确方法:如何处理React中的第三方dom操作?

我做了一个呈现代码并使用Highlight.js突出显示语法的组件。
它的工作,但内容更新时坏了。

class CodeBox extends React.Component { 
    componentDidMount() { 
     this.highlight(); 
    } 
    componentDidUpdate() { 
     this.highlight(); 
    } 
    highlight() { 
     hljs.highlightBlock(this.elem); 
    } 
    render() { 
     return (
      <pre><code ref={(elem) => { this.elem = elem }}>{this.props.code}</code></pre> 
     ); 
    } 
} 

我的理解是,作出反应处理code节点,当Highlight.js与它篡改不喜欢...所以我使出这样的:

class CodeBox extends React.Component { 
    componentDidMount() { 
     this.highlight(); 
    } 
    componentDidUpdate() { 
     this.highlight(); 
    } 
    highlight() { 
     this.elem.innerHTML = ""; 
     let c = document.createElement("code"); 
     c.innerHTML = this.props.code; 
     this.elem.appendChild(c); 
     hljs.highlightBlock(c); 
    } 
    render() { 
     return (
      <pre ref={(elem) => { this.elem = elem }}></pre> 
     ); 
    } 
} 

其中一期工程,但现在我觉得我正在使用React错误。
有没有办法做到这一点,不涉及直接操纵dom?

回答

0

您可以使用dangerouslySetInnerHTML在渲染后不使用refs或更改DOM来实现相同的结果,但由于Highlight.js的工作原理,您仍然必须使用假HTML元素。

要做到这一点,而不是使用componentDidUpdatecomponentDidMount方法,我们可以使用componentWillMountcomponentWillReceiveProps方法,像这样:

componentWillMount() { 
    this.highlight(this.props); 
} 
componentWillReceiveProps(newProps) { 
    this.highlight(newProps); 
} 
highlight(props) {   
    parseElement.innerHTML = props.code;   
    hljs.highlightBlock(parseElement); 
    this.setState({ 
     code: {__html: parseElement.innerHTML} 
    }); 
} 

,然后我们呈现出的渲染方法新的已经格式化代码:

return (
    <pre><code dangerouslySetInnerHTML={this.state.code} /></pre> 
); 

这里是一个JS Fiddle

这仍然是不是理想的,但它不会破坏React原则,同时仍然使用依赖额外DOM操作的Highlight.js。

+0

谢谢,那就是我一直在寻找的! –