反应插入节点对象



如果在 React 功能组件中我创建了一个这样的DOM node

const divElement = document.createElement("div");

将其注入组件所呈现的内容的最佳方法是什么?

例如

const MyComponent: React.FC<Props> = () => {
const divElement = document.createElement("div");
return (
<div className="my-component">{divElement}</div>
);
}

此示例不起作用。 它抛出一个错误说:

Objects are not valid as a React child

但它确实反映了我希望实现的解决方案类型,我可以以某种方式将元素直接渲染到内容中。

到目前为止,我发现让它工作的唯一方法是在我的组件容器div上使用 ref 并在ref上调用appenchChild(divElement). 但这对我来说不是一个理想的解决方案。

我也意识到,有更简单的方法可以实现我的例子正在做的事情。但是这个问题源于我正在使用的第三方库,它返回一个DOM node,我试图弄清楚如何注入它。

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

这将创建一个具有相同根类型的新组件并设置所有内部 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>
);
}

然后可以抽象到它自己的组件中

const DynamicComponent = ({ element }) => {
const reactElement = React.createElement(
element.nodeName.toLowerCase(),
{ dangerouslySetInnerHTML: { __html: element.innerHTML } },
null
);
return reactElement;
};

并用作

const el = document.createElement("div");
el.innerHTML = `<span style="color:red;">hello</span>`;
return (
<DynamicComponent element={el}>
);

您希望使用jsx 的语法,而不是使用原版 JavaScript 手动创建div 元素:

const MyComponent: React.FC<Props> = () => {
const divElement = (
<div></div>
)
return (
<div className="my-component">{divElement}</div>
);
}

当然,如果您使用的是返回 dom 节点的第三方库,您也可以使用React.createElement()语法,并手动提取节点类型并将其注入.createElement()参数中。

const divElement = React.createElement(
el.nodeName.toLowerCase(),
null,
{ dangerouslySetInnerHTML: { __html: el.innerHTML } 
});

另一种解决方法。至于我,带有参考的选项看起来更好。

render() {
const divElement = document.createElement("div");
divElement.innerHTML = "My Div";
function createMarkup() {
return {__html: divElement.outerHTML};
}
return (
<div>
<div dangerouslySetInnerHTML={createMarkup()}/>
</div>
);
}

最新更新