If within a React functional ponent I create a DOM node
like this
const divElement = document.createElement("div");
What would be the best way to inject that into what is being rendered by the ponent?
For instance
const MyComponent: React.FC<Props> = () => {
const divElement = document.createElement("div");
return (
<div className="my-ponent">{divElement}</div>
);
}
This example doesn't work. It throws an error saying :
Objects are not valid as a React child
But it does reflect the type of solution I'm hoping to achieve, where I can just render the element directly into the content somehow.
The only way I've found to get this to work so far is to use a ref on my ponent's container div
and call appenchChild(divElement)
on the ref
. But this is not an ideal solution for me.
I also realize that there are much easier ways to achieve what my example is doing. But this question stems from a thirdParty lib I'm using that returns a DOM node
and I'm trying to figure out how to inject it.
If within a React functional ponent I create a DOM node
like this
const divElement = document.createElement("div");
What would be the best way to inject that into what is being rendered by the ponent?
For instance
const MyComponent: React.FC<Props> = () => {
const divElement = document.createElement("div");
return (
<div className="my-ponent">{divElement}</div>
);
}
This example doesn't work. It throws an error saying :
Objects are not valid as a React child
But it does reflect the type of solution I'm hoping to achieve, where I can just render the element directly into the content somehow.
The only way I've found to get this to work so far is to use a ref on my ponent's container div
and call appenchChild(divElement)
on the ref
. But this is not an ideal solution for me.
I also realize that there are much easier ways to achieve what my example is doing. But this question stems from a thirdParty lib I'm using that returns a DOM node
and I'm trying to figure out how to inject it.
3 Answers
Reset to default 2https://codesandbox.io/s/clever-bassi-0kq6y
This will create a new ponent with the same root type and set all inner html
import React from "react";
import ReactDOM from "react-dom";
const el = document.createElement("div");
el.innerHTML = `<span style="color:red;">hello</span>`;
function App() {
const MyComponent = () => {
const MyElement = React.createElement(
el.nodeName.toLowerCase(),
{ dangerouslySetInnerHTML: { __html: el.innerHTML } },
null
);
return MyElement;
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<MyComponent />
</div>
);
}
Which can then be abstracted into it's own ponent
const DynamicComponent = ({ element }) => {
const reactElement = React.createElement(
element.nodeName.toLowerCase(),
{ dangerouslySetInnerHTML: { __html: element.innerHTML } },
null
);
return reactElement;
};
and used as
const el = document.createElement("div");
el.innerHTML = `<span style="color:red;">hello</span>`;
return (
<DynamicComponent element={el}>
);
You'd want to use the syntax for jsx rather than manually creating a div element with vanilla javascript:
const MyComponent: React.FC<Props> = () => {
const divElement = (
<div></div>
)
return (
<div className="my-ponent">{divElement}</div>
);
}
Of course, if you're using a third-party library that returns a dom node, you could use the React.createElement()
syntax as well, and manually extract the node type and inject it into the .createElement()
params.
const divElement = React.createElement(
el.nodeName.toLowerCase(),
null,
{ dangerouslySetInnerHTML: { __html: el.innerHTML }
});
Another workaround. As for me option with refs looks better.
render() {
const divElement = document.createElement("div");
divElement.innerHTML = "My Div";
function createMarkup() {
return {__html: divElement.outerHTML};
}
return (
<div>
<div dangerouslySetInnerHTML={createMarkup()}/>
</div>
);
}