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

时间:2017-11-16 16:04:41

标签: reactjs dom

使用像 renderjson (npm包)这样的库为Vanilla JS轻松地将一些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,而不是一个STRING。请注意,我在这里尝试将HTML字符串转换为反应HTML。我试图将HTMLElement转换为真正的ReactElement。

所以,我实际上设法做到了这一点,但是因为我将HTMLElement解析为一个字符串,所有onClick事件监听器都由 renderjson 在+和 - 句柄上生成(打开)或者崩溃json)在这个过程中很难......

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

我想,这里真正的问题是: renderjson 包怎样才能重新包装"成为React友好?

Here is a codesandbox to make it easier to see what I'm talking about here.

1 个答案:

答案 0 :(得分:0)

很好的问题,对于返回DOM元素的非反应式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/>;
  }
}

这样做是呈现div,并且在安装组件时会找到div并在其中添加库生成的HTMLElement。很简单。

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

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

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

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