反应& d3组合可防止mousedown事件

时间:2016-06-20 16:33:37

标签: javascript d3.js reactjs d3v4

我正在使用与d3(新的v4)一起做出反应,但似乎d3缩放行为与处理反应事件的方式相冲突。

我正在尝试将mousedown事件侦听器附加到<rect> svg元素。出于某种原因,当通过react连接侦听器时,在侦听器附加的反应之前触发d3侦听器。因为d3会阻止任何进一步的传播,所以我的侦听器永远不会被调用。

但是当我通过纯javascript直接附加监听器或禁用缩放行为时,它可以工作。

See this example on codepen

class Rectangle extends React.Component {
  componentDidMount() {
    // get main d3 selector
    this.canvas = d3.select('#react-root svg');
    // init the pan & zoom behaviour
    this.zoom = d3.zoom()
      .on('start', () => {
        console.log('zoom started!');
      })
      .on('zoom', () => {
        console.log('zooming!');
      });
    this.canvas.call(this.zoom);

    document.addEventListener('mousedown', () => {
      console.log("window mousedown!");
    });

    document.querySelector('#react-root svg rect').addEventListener('mousedown', () => {
      console.log('rect mousedown! (via pure js)');
    });
  }

  render() {
    return (
      <svg onMouseDown={() => console.log('svg mousedown! (via react)')}>
        <rect
          rx="10" ry="10"
          width="100" height="100"
          onMouseDown={() => console.log('rect mousedown! (via react)')}
          onTouchStart={() => console.log('touch down!')}
        />
      </svg>
    );
  } 
}

ReactDOM.render(<Rectangle />, document.getElementById('react-root'));

有什么建议吗?谢谢!

1 个答案:

答案 0 :(得分:0)

我猜D3会在组件安装后从<rect>删除您的React Events。

这不是问题,因为D3允许您使用type.name为同一事件注册多个侦听器。

例如:start.native&amp; start.react

如何将此应用于您的代码?喜欢这个

class Rectangle extends React.Component {
  componentDidMount() {
    this.canvas = d3.select('#react-root svg');
    this.zoom = d3.zoom()
      .on('start.native', () => {
        console.log('mouse down using pure js');
      })
      .on('end.native', () => {
        console.log('mouse up using pure js');
      })
      .on('start.react',this.onMouseDownWithReact)
      .on('end.react', this.onMouseUpWithReact);
    this.canvas.call(this.zoom);
  }
  onMouseDownWithReact(){
    console.log("Mouse Down with react");
  }
  onMouseUpWithReact(){
    console.log("Mouse Up with react");
  }
  render() {
    return (
      <svg onMouseDown={() => console.log('svg mousedown! (via react)')}>
        <rect
          rx="10" ry="10"
          width="100" height="100"
        />
      </svg>
    );
  }
}