【问题标题】:React & d3 combination prevents mousedown eventReact 和 d3 组合可防止 mousedown 事件
【发布时间】:2016-06-20 16:33:37
【问题描述】:

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

我正在尝试将 mousedown 事件侦听器附加到 <rect> svg 元素。由于某种原因,当通过 react 附加侦听器时,d3 侦听器在通过 react 附加侦听器之前触发。因为 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'));

有什么建议吗?谢谢!

【问题讨论】:

    标签: javascript reactjs d3.js


    【解决方案1】:

    我猜想 D3 在组件挂载后会从 &lt;rect&gt; 中删除你的 React 事件。

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

    例如:start.native & 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>
        );
      }
    }
    

    【讨论】:

    • 感谢您的建议,但如果可能的话,我实际上想继续使用绑定事件侦听器的反应方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多