2016-08-26 13 views
2

私はリアクションに慣れていて、次の状況を処理する正しい方法がわからない: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

が機能するために、依然として偽のHTML要素を使用する必要があるため、レンダリング後にrefを使用したりDOMを変更せずに同じ結果を得るには、dangerouslySetInnerHTMLを使用できます。

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} 
    }); 
} 

し、我々はrenderメソッドで新しい既にフォーマットコードアウトレンダリング:

を代わりに、我々はそうのような componentWillMountcomponentWillReceivePropsメソッドを使用することができます componentDidUpdatecomponentDidMountメソッドを使用しての、これを行うには

ここで

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

これはまだあるJS Fiddle

です理想的ではありませんが、追加のDOM操作に依存するHighlight.jsを使用しながら、Reactの原則を破ることはありません。

+0

ありがとう、それは私が探していたものです! –

関連する問題