Hello and thank you for reading this question.
I had an use case in which I needed to detect mouse coordinates on canvas, and thank you to @Carlos Martinez : getting mouse coordinates in React it works as expected.
I tryed to go further and detect if user clicks on canvas and then put on a h2 it, using state, and log it; and here is the code I have tryed:
import React from 'react';
class Canvas extends React.Component {
//A canvas to display images with a title
constructor(props) {
super(props);
this.state = {x: 0, y: 0, inside: ''};
this.handleClick = this.handleClick.bind(this);
}
_onMouseMove(e) {
this.setState({x: e.nativeEvent.offsetX, y: e.nativeEvent.offsetY});
}
componentDidMount() {
document.addEventListener('click', this.handleClick);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClick);
}
handleClick(e) {
console.log('INSIDE');
this.setState({inside: 'inside'});
}
render() {
const {x, y, inside} = this.state;
return (
<div className="previewComponent">
<div className="imgPreview">
{this.props.title}
<img src={this.props.image} alt="" onMouseMove={this._onMouseMove.bind(this)}
onClick={this.handleClick.bind(this)}/>
<h1>Mouse coordinates: {x} {y}</h1>
<h2>Inside?: {inside}</h2>
</div>
</div>
)
}
}
export {Canvas};
I expected that it would log it just once, and also put it on h2 tag.
However, unexpectedly it logs INSIDE, and then in addition logs two INSIDE:
INSIDE
2 Canvas.js:29 INSIDE
Could you explain me this behaviour? Also, it would be appreciated some tips to fix it and just print one log per click!
EDIT:
I have tried @Or B answer and I understood it however it looks like it stills showing the same behaviour, 3 logs of INSIDE instead of one:

The code is:
handleClick(e) {
e.stopPropagation();
console.log('INSIDE');
this.setState({inside: 'inside'});
}
This happens due to event propagation and the fact that you're listening to click events on the entire document.
Clicking on the <img> not only generates a click event for the image, but also for the two wrapping <div> elements. These two are captured by the document, which is why it's being logged two more times. If you log e.target you could see which element triggered the event.
In order to prevent it from propagating, use event.stopPropagation():
handleClick(e) {
e.stopPropagation();
console.log('INSIDE');
this.setState({inside: 'inside'});
}
This is because click handler is being called twice. Once by the canvas onClick component and the second time by the click handler inside the componentWillMount function. Also, the componentWillMount function listens to the clicks on the entire document because of the document.addEventListener part. I would simply use the componentWillMount to set states.
Remove the document.addEventListener part and it should be good to go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With