Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React insert node object

If within a React functional component 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 component?

For instance

const MyComponent: React.FC<Props> = () => {
    const divElement = document.createElement("div");
    return (
        <div className="my-component">{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 component'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.

like image 534
jdavis Avatar asked Oct 16 '22 10:10

jdavis


2 Answers

https://codesandbox.io/s/clever-bassi-0kq6y

This will create a new component 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 component

  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}>
);
like image 108
tic Avatar answered Oct 19 '22 02:10

tic


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-component">{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 } 
});
like image 22
silencedogood Avatar answered Oct 19 '22 02:10

silencedogood