将 HTMLElement 转换为 React 元素,并保留任何事件侦听器

Converting HTMLElement to a React Element, and keeping any event listeners

提问人:b00stup 提问时间:11/17/2017 更新时间:12/23/2018 访问量:7363

问:

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

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);

在反应世界中

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

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

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


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

这是一个代码沙箱,可以更容易地看到我在这里说的内容。

反应JS DOM

评论

0赞 Train 11/17/2017
为什么不将处理程序放在静态父容器中?
0赞 b00stup 11/18/2017
我不确定你所说的静态父容器是什么意思......谢谢你的回复!
0赞 Ritesh Bansal 4/20/2018
@b00stup 你做到了吗?我被困在同样的事情上。

答:

0赞 Kostis 12/23/2018 #1

好问题,我在返回 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/>;
  }
}

它的作用是渲染一个 ,当组件挂载时,它会找到 并在那里添加由您的库生成的。简单。divdivHTMLElement

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

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

这样,您的听众就可以正常工作。

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

评论

0赞 gabrielAnzaldo 3/12/2019
这仍然有效吗?我发现根据官方文档,ReactDOM.findDOMNode(component) 已被弃用
1赞 Kostis 3/13/2019
如果您访问上述方法的链接(来自 reactjs.org),它会说“它已在 StrictMode 中弃用”。无论如何,不鼓励使用这种方法,因为“它刺穿了组件抽象”。讨厌的事情,但这是一个快速的黑客。对于我正在构建的原型来说,这已经足够了。想不出一种干净的方法来将 HTMLElement 对象转换为 React 元素