首页 > 解决方案 > 将渲染输出反应为 HTML 而不是组件

问题描述

我正在编写一个显示组件的小型系统,并在它旁边显示源代码。这对开发人员来说非常棒。但是,在某些情况下,我需要原始 HTML。摆脱这个限制的唯一方法是复制代码

正常渲染:

<CustomComponent></CustomComponent>

将封装的代码渲染“美化”

<div><div>content</div></div>

我想做的是在我的应用程序中提供<CustomComponent>并能够正常渲染它以及封装的代码。我看过一些解决方案,但它们只提供呈现<CustomComponent></CustomComponent>标签的解决方案,而不是render方法内的内容。

标签: javascripthtmlreactjs

解决方案


如何渲染组件,然后使用效果挂钩将 html 作为字符串复制到 DOM 作为文本?

/**
 * Component that renders it's children, and then then puts the html source
 * equivalent of that component in a code tag.
 */
function ShowHtml({ children }) {
  // Use refs to store the nodes our after render hook will need.
  const component = useRef(null);
  const code = useRef(null);

  // After render, read the html from the DOM of the component, and insert it
  // as text into the target <code> element.
 useEffect(() => {
    if (code.current && component.current) {
      code.current.innerText = component.current.innerHTML;
    }
  });

  // Render the component, and the code tag.
  return (
    <div>
      <div ref={component}>{children}</div>
      <code ref={code} />
    </div>
  );
}

用法:

<ShowHtml>
  <Test />
</ShowHtml>

工作示例


警告:并非所有道具都放在 HTML 中。例如,事件处理程序使用纯 JavaScript 以不同的方式绑定到 DOM 元素。组件不仅仅是 HTML,因此无论如何,您都无法获得完整的图片。但是您应该使用这种方法获得实际上完全支持 HTML 的任何属性。


Refs 在第一次渲染时为空,因为组件必须存在才能在第一次渲染时获得引用。所以你必须处理它。

但是您的新沙箱还有另一个问题。如果您在渲染时需要源以传递给反应组件,那么您不能使用渲染后效果来执行此操作,因为渲染已完成。

因此,我将答案更改为:

import { renderToStaticMarkup } from 'react-dom/server'

使用该函数,您应该能够从任何渲染的反应节点获取字符串:

  <div ref={component}>{children}</div>
  <Highlight
    {...defaultProps}
    code={renderToStaticMarkup(children)}
    language={"html"}
  >

推荐阅读