I’m using a NodeView with React to render an image with a form. Here is a simplified version:
export class ImageView {
constructor(node, view, getPos) {
this.dom = document.createElement("div");
this.node = node;
this.view = view;
this.getPos = getPos;
this.onSave = newAttrs => {
this.view.dispatch(
this.view.state.tr.setNodeMarkup(this.getPos(), null, newAttrs),
);
};
this.renderComponent(node, false);
}
renderComponent(node, selected = true) {
this.select = () => {
let $pos = this.node.resolve(this.getPos());
let selection = NodeSelection.create(this.view.state.doc, this.getPos());
this.view.dispatch(this.view.state.tr.setSelection(selection));
};
ReactDOM.render(
<Image
src={node.attrs.src}
alt={node.attrs.alt}
alignment={node.attrs.alignment}
select={this.select}
selected={selected}
onSave={this.onSave}
/>,
this.dom,
);
}
update(node) {
if (node.type == this.node.type) {
this.node = node;
this.renderComponent(node);
return true;
}
return false;
}
selectNode() {
this.renderComponent(this.node);
}
deselectNode() {
this.renderComponent(this.node, false);
}
stopEvent() {
return true;
}
destroy() {
const res = ReactDOM.unmountComponentAtNode(this.dom);
}
ignoreMutation(e) {
return true;
}
}
I assume I’m doing something stupid but when the node is selected and I delete it after destroy
successfully unmounts the component the deselectNode
kicks in and renders it again (into a non-existent dom node). This way I end up with “ghost” react components.
I use deselectNode
to handle selection inside the image component as I have additional elements inside and I want the “blue frame” to show around the image only.