3

Hi I was playing around with creating a custom cursor in react. The cursor works fine, however a few seconds later after a few scrolls or changing pages, i get the following error: Uncaught TypeError: Cannot read property 'clientWidth' of null.

  //follows the cursor
  const customRef = React.useRef(null)
   
  React.useEffect(() => {
  document.addEventListener('mousemove', (e) => {
    const { clientX, clientY } = e
    const mouseX = clientX - customRef.current.clientWidth / 2
    const mouseY = clientY - customRef.current.clientHeight / 2
  customRef.current.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`
  })
  }, [])

  return (
    <div className="app-cursor" ref={customRef} />

  )
}

export default CustomCursor

Here's the CSS:

.app-cursor {
  z-index: 100;
  border-radius: 50%;
  width: 60px;
  height: 60px;
  border: 1px solid rgb(168, 163, 163);
  pointer-events: none;
  overflow: hidden; 
  transform: translate3d(0, 0, 0);
  position: fixed;
}

Any help would be appreciated.

Thanks in advance.

3
  • where is the "above error"? Commented Sep 15, 2020 at 17:04
  • Sorry if i wasn't clear in my question or title. The message is: Uncaught TypeError: Cannot read property 'clientWidth' of null. Commented Sep 15, 2020 at 17:10
  • This needs to be added to your question. Please consider editing. Commented Sep 15, 2020 at 17:15

1 Answer 1

2

The reason why you get the error is because you add the event listener but never removes it and in a certain point of your application, you unmount the element your are passing the ref, and when trying to access that ref, it doesn't exists.

You need to remove the event listener in the cleanup effect of the useEffect.

const CustomCursor = () => {
    //follows the cursor
    const customRef = React.useRef(null)
   
    useEffect(() => {
      const onMouseMove = (e) => {
        const { clientX, clientY } = e
        const mouseX = clientX - customRef.current.clientWidth / 2
        const mouseY = clientY - customRef.current.clientHeight / 2
        customRef.current.style.transform = `translate3d(${mouseX}px, ${mouseY}px, 0)`
      }
      // add the event listener
      document.addEventListener('mousemove', onMouseMove)
      // cleanup function
      return () => {
        // remove the event listener when the component unmounts
        document.removeEventListener('mousemove', onMouseMove)
      }
    }, [])
  
    return (
      <div className="app-cursor" ref={customRef} />
    )
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your detailed response! It worked like a treat and has inspired me to read up on the topic to gain better understanding! Have a great day! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.