首页 > 解决方案 > 是否可以从 html 事件处理程序调用 React

问题描述

我正在使用带有 React.js 的 d3 绘图库,并且遇到了从 SVG 元素触发 onClick 事件的问题。

当我单击 SVG 中的一个元素时,我想要做的是调用一个函数(从 props 中的父级传递)。问题在于 SVG 的元素是由 d3 生成的,而不是反应组件。有什么办法可以使这项工作?

对于那些不熟悉 d3 的人来说,它提供了一种非常流畅的语法来从一组数据生成和更新 svg。代码看起来像这样:

      const existingNodes = d3Select('.nodes')
        .selectAll('g.node')
        .data(root.descendants());
      const newNodes = existingNodes.enter().append('g');
      newNodes
        .append('circle')
        .attr('onclick', (node) => 'onNodeSelected("Test")')
        .attr('r', (node) => nodeRadius(node.data));

这段代码的问题在于,.attr('onclick', (node) => 'onNodeSelected("Test")')它正确地onclick向圆圈添加了一个属性,但当然onNodeSelected是反应组件的一个道具,不能像这样访问。

为了提供一些上下文,React 组件的缩写代码如下所示:

export const HierarchyDiagram = ({ onNodeSelected, hierarchyData }) => {

  useEffect(() => {
    function buildSvg(root) {
    ...abbreviated
      const existingNodes = d3Select('.nodes')
        .selectAll('g.node')
        .data(root.descendants());
      const newNodes = existingNodes.enter().append('g');
      newNodes
        .append('circle')
        .attr('onclick', (node) => 'onNodeSelected({node})')
        .attr('r', (node) => nodeRadius(node.data));
    ....abbreviated
    }

    if (hierarchyData) {
      buildSvg(hierarchyData);
    }
  }, [hierarchyData]);

  return (
    <svg width="100%" height="100%">
      <g className="wrapper">
        <g className="links"></g>
        <g className="nodes"></g>
      </g>
    </svg>
  );
};

标签: javascriptreactjssvgd3.js

解决方案


如果要附加onclick事件,请使用on. 这应该有效:

.append('circle')
.on('click', (evt, node) => {
  onNodeSelected(node);
  d3.event.stopPropagation(); // stop the event propagation
});

推荐阅读