我是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?
答案 0 :(得分:0)
您可以使用dangerouslySetInnerHTML
在渲染后不使用引用或更改DOM来获得相同的结果,但是由于Highlight.js
的工作方式,您仍然必须使用虚假的HTML元素。
要执行此操作,我们可以使用componentDidUpdate
和componentDidMount
方法,而不是使用componentWillMount
和componentWillReceiveProps
方法:
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>
);
这仍然不理想,但它不会破坏React原则,同时仍然使用依赖于其他DOM操作的Highlight.js。