2016-06-20 2 views
1

d3 (새로운 v4)과 함께 반응하지만 d3 확대/축소 동작이 반응 이벤트 처리 방식과 충돌하는 것 같습니다.React & d3 combination으로 mousedown 이벤트 방지

<rect> svg 요소에 mousedown 이벤트 리스너를 연결하려고합니다. 어떤 이유로 리액션을 통해 리스너를 부착 할 때 반응을 통해 연결된 리스너보다 먼저 d3 리스너가 트리거됩니다. d3은 전파가 더 이상 중단되기 때문에 리스너가 호출되지 않습니다.

그러나 순수한 자바 스크립트를 통해 리스너를 직접 연결하거나 확대/축소 동작을 비활성화하면 작동합니다.

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

어떤 제안? 감사!

답변

0

D3가 컴포넌트가 마운트 된 후 <rect>에서 귀하의 반응 이벤트를 제거하고있는 것 같습니다.

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> 
    ); 
    } 
} 
+0

제안 해 주셔서 감사합니다.하지만 가능한 경우 이벤트 리스너를 바인딩하는 반응 방식을 계속 사용하고 싶습니다. – kulturfunker