I have a code that is supposed to add event listener on a parent component when element is clicked and remove it when the mouse is up but the removing of event listener is not working.
const move = (e)=>{
setPosition({top:e.clientY-50,left:e.clientX-65})
}
const handleMouseDown = (e) =>{
backgroundRef.current.addEventListener('mousemove',(e)=>move(e))
}
const handleMouseUp = (e) =>{
backgroundRef.current.removeEventListener('mousemove',(e)=>move(e))
}
return <div ref={iconRef} onm ouseDown={handleMouseDown} onm ouseUp={handleMouseUp} style={position} className='icon-container' >
<img draggable='false' src={image} alt=''/>
<p>{text}</p>
</div>
CodePudding user response:
You need to pass the same function reference to both addEventListener and removeEventListener. You are currently passing a new anonymous function on each call.
const move = (e)=>{
setPosition({top:e.clientY-50,left:e.clientX-65})
}
const handleMouseDown = (e) =>{
backgroundRef.current.addEventListener('mousemove',move) // passing the same reference
}
const handleMouseUp = (e) =>{
backgroundRef.current.removeEventListener('mousemove',move) // passing the same reference
}
CodePudding user response:
I think for removeEventListener
to work in this case, in addition to passing the reference equal move
for it, the functions might also need to be saved by useCallback
. Because when state position
changes and the component re-renders, handleMouseUp
could be recreated with a new copy of move
already.
Example with reference equal move
and useCallback
:
const Child = ({ image, text, backgroundRef }) => {
const [position, setPosition] = React.useState(null);
const move = React.useCallback((e) => {
setPosition({
top: `${e.clientY - 50}px`,
left: `${e.clientX - 65}px`,
});
}, []);
const handleMouseDown = React.useCallback(() => {
backgroundRef.current.addEventListener('mousemove', move);
}, [move]);
const handleMouseUp = React.useCallback(() => {
backgroundRef.current.removeEventListener('mousemove', move);
}, [move]);
return (
<div
onm ouseDown={handleMouseDown}
onm ouseUp={handleMouseUp}
style={position}
className="icon-container"
>
<img draggable="false" src={image} alt="" />
<p>{text}</p>
</div>
);
};
const Parent = () => {
const backgroundRef = React.useRef(null);
return (
<section ref={backgroundRef}>
<Child
text="