Skip to content

Instantly share code, notes, and snippets.

@infinnie
Created September 10, 2018 10:42
Show Gist options
  • Save infinnie/f1cf28559662501291152813844bb64a to your computer and use it in GitHub Desktop.
Save infinnie/f1cf28559662501291152813844bb64a to your computer and use it in GitHub Desktop.
Hook the document fragment.
var SomeReactComponent = class extends React.Component {
render() {
return this.props.render();
}
};
export default {
props: {
reactComponent: Function,
reactComponentProps: {
type: Object,
default() {
return {};
}
}
},
render: function (h) {
return h("span", {
style: {
display: "none"
}
});
},
mounted: function () {
/**
* @type{HTMLSpanElement}
*/
var el = this.$el,
parent = el.parentElement,
frag = document.createDocumentFragment(),
comment = document.createComment("This is a comment from SomeComponent");
parent.replaceChild(comment, el);
proxyEventListeners(frag, parent);
var origRemoveChild = frag.removeChild, origAppendChild = frag.appendChild;
this.boundReactComponent = ReactDOM.render(<SomeReactComponent render={
() => <this.reactComponent {...this.reactComponentProps} />}
/>, frag);
var fragChildren = [].slice.call(frag.children), fragTimer = 0;
parent.insertBefore(frag, comment);
this.fragment = frag;
frag.removeChild = function () {
var ret;
if (!fragTimer) {
if (fragChildren.length) {
fragChildren.forEach(x => origAppendChild.call(frag, x));
}
ret = origRemoveChild.apply(frag, arguments);
fragTimer = setTimeout(() => {
fragTimer = 0;
fragChildren = [].slice.call(frag.children);
parent.insertBefore(frag, comment);
}, 0);
} else {
ret = origRemoveChild.apply(frag, arguments);
}
return ret;
};
frag.appendChild = function () {
var ret;
if (!fragTimer) {
if (fragChildren.length) {
fragChildren.forEach(x => origAppendChild.call(frag, x));
}
ret = origAppendChild.apply(frag, arguments);
fragTimer = setTimeout(() => {
fragTimer = 0;
fragChildren = [].slice.call(frag.children);
parent.insertBefore(frag, comment);
}, 0);
} else {
ret = origAppendChild.apply(frag, arguments);
}
return ret;
};
},
updated: function () {
console.log(1);
},
watch: {
reactComponentProps: function (props) {
console.log("react component props changed");
this.boundReactComponent.forceUpdate();
}
},
beforeDestroy: function () {
console.log("Destroying");
ReactDOM.unmountComponentAtNode(this.fragment);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment