So as per documentation in React, the initial state of the below code of canMove is true. I changed it to false.
import React from "react";
import "./style.css";
import { useState, useEffect } from 'react';
export default function App() {
const [position, setPosition] = useState({ x: 0, y: 0 });
const [canMove, setCanMove] = useState(false);
useEffect(() => {
function handleMove(e) {
setPosition({ x: e.clientX, y: e.clientY });
}
if (canMove)
window.addEventListener('pointermove', handleMove);
return () => window.removeEventListener('pointermove', handleMove);
}, [canMove]);
return (
<>
<label>
<input type="checkbox"
checked={canMove}
onChange={(e) => {
setCanMove(e.target.checked)
}
}
/>
The dot is allowed to move
</label>
<hr />
<div style={{
position: 'absolute',
backgroundColor: 'pink',
borderRadius: '50%',
opacity: 0.6,
transform: `translate(${position.x}px, ${position.y}px)`,
pointerEvents: 'none',
left: -20,
top: -20,
width: 40,
height: 40,
}} />
</>
);
}
So after first render, useEffect
runs but adding event listener to "pointermove"
is dependent on canMove
which is now false and hence no event listener is added. Now if we click the checkbox, canMove
is true this triggers the useEffect
again, and the cleanup should run first. But there is no handlemove
function added to pointer move previously. So this line should give error logically?
It's not an error to enqueue removal of an event listener... if it exists then it will be removed, otherwise, it's ignored. See EventTarget: removeEventListener:
Calling
removeEventListener()
with arguments that do not identify any currently registered event listener on theEventTarget
has no effect.
This means your current/initial code is ok, no error should be thrown because an event listener wasn't added previously.