I\'m gradually replacing some Backbone views with React.
My React View:
Rendered By React
This appears to work:
const linkEl = <link href="https://fonts.googleapis.com/css?family=Cinzel&display=swap" rel="stylesheet"/>;
const linkElAsDirectChildOfHead = ReactDOM.createPortal(linkEl, document.head); // portal will do actual adding-to-head
ReactDOM.render(linkElAsDirectChildOfHead, document.createElement("div")); // render stub into never-added container
The result:
Note that, as desired, it doesn't delete the other children within document.head.
Not sure if this method has any negative side-effects, but at first glance it appears to work.
That should do it:
* Replaces html node with react component
* @param element
* @param reactComponent
*/
export function replaceNodeWithReactComponent (element: HTMLElement, reactComponent: any) {
const parent = document.createElement('div');
ReactDOM.render(reactComponent, parent, () => {
element.replaceWith(...Array.from(parent.childNodes));
});
}
Usage:
replaceNodeWithReactComponent(myHTMLelement, <MyReactComponent />);
Unfortunately there is no way to do that currently with React. It replaces the contents of whatever element you render into.
The best you can do for now is render the React component separately and then mutate the DOM manually to get it where you want it.
I expect the functionality you seek will be available in React before long, but not yet!
You don't need jQuery to work around this issue.
You just need to render into a temporary DIV and extract the content and replace the existing element. I've added the id="destination"
so that the element can be easily retrieved from the temporary element.
var Hello = React.createClass({
render: function() {
return <div id="destination">Hello {this.props.name}</div>;
}
});
// temporary render target
var temp = document.createElement("div");
// render
React.render(<Hello name="World" />, temp);
// grab the container
var container = document.getElementById("container");
// and replace the child
container.replaceChild(temp.querySelector("#destination"), document.getElementById("destination"));