如何在React中处理第三方dom操作?

时间:2016-08-26 23:26:14

标签: javascript dom reactjs

我是React的新手,不知道处理以下情况的正确方法是什么:

我创建了一个呈现代码的组件,并使用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>
        );
    }
}

我的理解是React处理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?

1 个答案:

答案 0 :(得分:0)

您可以使用dangerouslySetInnerHTML在渲染后不使用引用或更改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}
    });
}

然后我们在render方法中渲染出已经格式化的新代码:

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

这是JS Fiddle

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