I am using react-scratchcard-v2 to create a scratchcard game. It works fine on desktop, but when using it with touch (either on mobile or in the mobile view of Dev Tools), it still works, but I get his error:

react-dom.development.js:6878 Unable to preventDefault inside passive event listener invocation. preventDefault @ react-dom.development.js:6878 Scratch2._this.handleMouseMove @ index.tsx:197 callCallback2 @ react-dom.development.js:4164 invokeGuardedCallbackDev @ react-dom.development.js:4213 invokeGuardedCallback @ react-dom.development.js:4277 invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291 executeDispatch @ react-dom.development.js:9041 processDispatchQueueItemsInOrder @ react-dom.development.js:9073 processDispatchQueue @ react-dom.development.js:9086 dispatchEventsForPlugins @ react-dom.development.js:9097 (anonymous) @ react-dom.development.js:9288 batchedUpdates$1 @ react-dom.development.js:26140 batchedUpdates @ react-dom.development.js:3991 dispatchEventForPluginEventSystem @ react-dom.development.js:9287 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465 dispatchEvent @ react-dom.development.js:6457 dispatchContinuousEvent @ react-dom.development.js:6444

That's my code:

import "./style.css";
import { useEffect, useState } from "react";
import ScratchCard from "react-scratchcard-v2";

const scratchingSound = new Audio("./sounds/scratching.mp3");
scratchingSound.loop = true;

interface IScratchAreaProps {
  value: 0 | 10 | 100 | 1000;
}

const ScratchArea = ({ value }: IScratchAreaProps) => {
  const [
    amount,
    // setAmount
  ] = useState(value);
  const [
    amountSrc,
    // setAmountSrc
  ] = useState(`./assets/${amount}.svg`);
  const [
    iconSrc,
    // setIconSrc
  ] = useState(amount === 0 ? "./assets/banana.svg" : "./assets/coin.svg");

  const [isClicked, setIsClicked] = useState(false);
  const [isScratching, setIsScratching] = useState(false);

  const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
    if (event.button === 0) {
      setIsClicked(true);
      setIsScratching(true);
    }
  };

  const handleMouseUp = () => {
    setIsClicked(false);
    setIsScratching(false);
  };

  const handleMouseEnter = () => {
    if (isClicked) {
      setIsScratching(true);
    }
  };

  const handleMouseLeave = () => {
    if (isClicked) {
      setIsScratching(false);
    }
  };

  useEffect(() => {
    const handleWindowMouseUp = () => {
      if (isClicked) {
        setIsClicked(false);
        setIsScratching(false);
      }
    };
    window.addEventListener("mouseup", handleWindowMouseUp);

    return () => {
      window.removeEventListener("mouseup", handleWindowMouseUp);
    };
  }, [isClicked]);

  useEffect(() => {
    const handleWindowMouseUp = () => {
      if (isClicked) {
        setIsClicked(false);
        setIsScratching(false);
      }
    };

    window.addEventListener("mouseup", handleWindowMouseUp);

    return () => {
      window.removeEventListener("mouseup", handleWindowMouseUp);
    };
  }, [isClicked]);

  useEffect(() => {
    if (isScratching) {
      scratchingSound.currentTime = 0;
      scratchingSound.volume = 0.3;
      scratchingSound.play();
    } else {
      scratchingSound.pause();
    }
  }, [isScratching]);

  return (
    <div
      className="scratcharea-container"
      onMouseDown={handleMouseDown}
      onMouseUp={handleMouseUp}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      <ScratchCard
        width={170}
        height={170}
        image="./assets/scratch_card.svg"
        finishPercent={60}
        onComplete={() => console.log("complete")}
        brushSize={15}
        fadeOutOnComplete={false}
      >
        <div className="scratcharea">
          <img className="revealed-icon" alt="revealed icon" src={iconSrc} />
          <img
            className="revealed-amount"
            alt="revealed amount"
            src={amountSrc}
          />
        </div>
      </ScratchCard>
      <div
        onClick={() => console.log("Help modal opened!")}
        className="help-button"
      />
    </div>
  );
};

export default ScratchArea;

I tried removing all event handlers, but the error persists. There is also a live deployment if you want to check it: Deployment

Thanks for any help.

0

There are 0 best solutions below