将 HTMLElement 转换为 React Element,并保留所有事件侦听器

b00*_*tup 6 dom reactjs

将一些 JSON 数据渲染成一组可折叠的 HTML 元素是很容易的,使用像用于 Vanilla JS 的renderjson(npm 包)这样的库

const data = { sample: [1, 2, 3, 4], data: { a: 1, b: 2, c: ["hello", null] } };
const rjson = renderjson(data);
document.getElementById('to-render').append(rjson);
Run Code Online (Sandbox Code Playgroud)

在反应世界中

但是,renderjson返回一个 HTMLElement,而不是一个字符串。请注意,我不只是在这里尝试将 HTML 字符串转换为 React HTML。我正在尝试将 HTMLElement 转换为真正的 ReactElement。

所以,我实际上设法做到了这一点,但是由于我将 HTMLElement 解析为一个字符串,因此在 + 和 - 句柄(打开或折叠 json)上由renderjson生成的所有 onClick 事件侦听器在此过程中都丢失了.. ..

有没有人知道如何将 HTMLElement 对象转换为 React Element,同时保留所有原始事件处理程序?


我想,这里真正的问题是:renderjson包如何“重新打包”以变得对 React 友好?

这是一个代码和框,可以更容易地看到我在这里谈论的内容。

Kos*_*tis 0

好问题,我不断遇到返回 DOM 元素的非 React JS 库的类似问题。这些库应该移植到 React,但如果您不想这样做,您可以使用findDomNode()获取 DOM(而不是 React)节点,并将其附加HTMLElement到那里。请注意,在官方文档中,不鼓励使用它,因为“它穿透了组件抽象”。无论如何,在您的示例中,您可以添加一个包装类:

class JsonTreeWrapper extends Component {
  componentDidMount() {
    const renderedJson = renderjson(this.props.data);

    const container = findDOMNode(this);
    container.appendChild(renderedJson);
  }

  render() {
    return <div/>;
  }
}
Run Code Online (Sandbox Code Playgroud)

它的作用是渲染 a div,当组件安装时,它会找到 adiv并将HTMLElement您的库生成的添加到那里。简单的。

在你的 中App,你可以像这样使用它:

class App extends Component {
  render() {
    return (
      <div>
        <h1> Inside the react world </h1>
        <JsonTreeWrapper data={data}/>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这样你的听众就会工作得很好。

Codesandbox 对我不起作用,但您可以在此处查看演示。我希望这有帮助!