项目中的操作手册部分需要进行代码高亮展示,引入了第三方插件prism.js
为了便于整个项目中使用,将其封装成一个组件。
import React from "react";
import Prism from "prismjs";
interface PropsType {
language: any; code: any;
}
export default class PrismCode extends React.PureComponent<PropsType, {}> {
ref: any;
constructor(props: any) {
super(props);
this.ref = React.createRef();
}
componentDidMount() {
this.highlight();
}
highlight = () => {
if (this.ref && this.ref.current) {
Prism.highlightElement(this.ref.current); // 会导致Error
}
}
render() {
const { language, code} = this.props;
return (// pre是prism的用法
<pre className="line-numbers">
<code ref={this.ref} className={`language-${language}`}>
{code.trim()}
</code>
</pre>
);
}
}
在切换两个相邻的menu时,如果都需要调用该组件,会报错NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
经过分析发现是使用组件的问题,考虑DOM-DIff算法是比对不同的React节点,而该组件的渲染直接是第三方插件的代码,在componentDidMount阶段才进行DOM节点的挂载,在此之前是没有node节点的,故需要增加一个可识别的node节点。
return (
<div>
<pre className="line-numbers">
<code ref={this.ref} className={`language-${language}`}>
{code.trim()}
</code>
</pre>
</div>
);
问题解决了~~~