[英]How to handle third-party dom manipulation in React?
I am new to React and not sure what is the proper way of dealing with the following situation: 我是React的新手,不确定如何处理以下情况:
I made a component that renders code and uses Highlight.js to highlight the syntax. 我制作了一个呈现代码并使用Highlight.js突出显示语法的组件。
It worked, but broke when the content updated. 它有效,但是在内容更新时中断了。
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>
);
}
}
My understanding is that React handles the code
node, and doesn't like when Highlight.js tampers with it... so i resorted to this: 我的理解是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>
);
}
}
Which works, but now i feel like i'm using React wrong. 哪个可行,但现在我感觉我使用React错误。
Is there a way to do this that doesn't involve directly manipulating the dom ? 有没有办法不涉及直接操纵dom的方法呢?
You can use dangerouslySetInnerHTML
to achieve the same result without using refs or altering the DOM after rendering, however because of how Highlight.js
works, you still have to use a fake HTML element. 您可以使用
dangerouslySetInnerHTML
地设置内部HTML来获得相同的结果,而无需在渲染后使用引用或更改DOM,但是由于Highlight.js
工作方式,您仍然必须使用伪造的HTML元素。
To do this, instead of using the componentDidUpdate
and componentDidMount
methods we can use the componentWillMount
and componentWillReceiveProps
methods like so: 要做到这一点,而不是使用
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}
});
}
and then we render out the new already formatted code in the render method: 然后在render方法中渲染出新的已经格式化的代码:
return (
<pre><code dangerouslySetInnerHTML={this.state.code} /></pre>
);
this is still not ideal, but it doesn't break React principles, while still using Highlight.js that relies on additional DOM manipulations. 这仍然不是理想的,但是它没有违反React原则,同时仍然使用Highlight.js依赖其他DOM操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.