2016-08-26 69 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

謝謝,那就是我一直在尋找的! –