为什么我的nextjs按钮没有调用函数

问题描述 投票:0回答:1

我有一个用于创建动画的下一个应用程序。这些帧被保存到时间线上,用户可以在其中滚动旧帧。我试图添加一个简单的功能,通过单击附加按钮来删除其中一个框架,但即使语法与任何其他函数相同并且没有错误,该函数也不会被调用。这是组件、父组件和 package.json:

import React from "react";
import { useCanvas } from "./CanvasContext";
import { settings } from "./Signals";
import ReusableLayer from "../components/utility/ResuableLayer";
import { timeline } from "./Signals";
import { v4 as uuidv4 } from "uuid";
import IndexLabel from "../components/utility/IndexLabel";
import JSZip from "jszip";
import { saveAs } from "file-saver";
const Timeline: React.FC = () => {
  const handleDownloadImages = () => {
    const zip = new JSZip();

    // Add each image to the zip file
    timeline.value.forEach((imageDataURL, index) => {
      const base64Data = imageDataURL.split(",")[1];
      zip.file(`image_${index + 1}.png`, base64Data, { base64: true });
    });

    // Generate the zip file and trigger download
    zip.generateAsync({ type: "blob" }).then((blob) => {
      saveAs(blob, "timeline_images.zip");
    });
  };

  const handleDeleteImage = (index: number, e: React.MouseEvent) => {
    e.stopPropagation();
    console.log("click");

    // Create a copy of the timeline array
    const updatedImages = [...timeline.value];

    // Modify the copy
    updatedImages.splice(index, 1);

    // Update the timeline array with the modified copy
    timeline.value = updatedImages;

    console.log("splicing");
  };

  const timelineImageSize = 400

  return (
    <div className="relative w-full overflow-x-auto bg-gray-200">
      <div
        className="flex h-auto overflow-y-hidden flex-row-reverse gap-1 py-1"
        style={{
          width:
            (timelineImageSize) * timeline.value.length - 0
            // settings.value.canvasSize.x,
        }}
      >
        {timeline.value.map((imageDataURL, index) => (
          <div
            className="relative border-2"
            key={uuidv4()}
            style={{
              border: "black 1px solid",
              width:  (timelineImageSize),
              height:  (timelineImageSize),
            }}
          >
            <button
              onClick={(e) => handleDeleteImage(index, e)}
              className="z-50 top-0 right-0 p-2 bg-red-500 text-white rounded-md cursor-pointer"
            >
              Delete
            </button>
            <button
              onClick={(e) => handleDeleteImage(index, e)}
              className=" "
            >
              Delete
            </button>
            <img
              src={imageDataURL}
              width={timelineImageSize} // Render two times smaller
              height={timelineImageSize} // Render two times smaller
              alt={`Image ${index}`}
            />
            {/* <IndexLabel
              label={(index + 1).toString()}
              customClasses="absolute top-0 left-0 text-lg"
            /> */}
          </div>
        ))}
      </div>
      {timeline.value.length > 0 && (
        <button
          // onClick={handleDownloadImages}
          className="mt-4 p-2 bg-blue-500 text-white rounded-md cursor-pointer absolute bottom-0 right-0"
        >
          Download Images
        </button>
      )}
      <button
        onClick={
          (e) => handleDeleteImage(0, e )
         }
        className="z-10   top-0 right-0 p-2 bg-red-500 text-white rounded-md cursor-pointer"
      >
        Delete
      </button>
    </div>
  );
};
 
parent component:
const Page: React.FC = () => {
  const {   canvasRef, frontlineCanvasRef, markerCanvasRef,backgroundCanvasRef } =
    useCanvas();
  const { GlobalData, updateGlobalData } = useGlobalValue();
  const [mouseDownTimeStamp, setMouseDownTimeStamp] = useState<number | null>(
    null
  );
  const [elapsedTime, setElapsedTime] = useState<number>(0);

  const handleMouseDown = (e:  MouseEvent) => {
    if (e.button === 2) {
      e.preventDefault();
    }
    setMouseDownTimeStamp(Date.now());
  };

  const handleMouseUp = (e:  MouseEvent) => {
    e.preventDefault();
    // Using requestAnimationFrame to delay the execution until the next frame
    requestAnimationFrame(() => {
      setElapsedTime(0);
      setMouseDownTimeStamp(null);
    });
  };

  useEffect(() => {
    // Add event listeners when the component mounts
    document.addEventListener("mousedown", handleMouseDown);
    document.addEventListener("mouseup", handleMouseUp, true);

    // Remove event listeners when the component unmounts
    return () => {
      document.removeEventListener("mousedown", handleMouseDown);
      document.removeEventListener("mouseup", handleMouseUp, true);
    };
  }, []);

  useEffect(() => {
    // Update elapsed time while the button is pressed
    if (mouseDownTimeStamp !== null) {
      const intervalId = setInterval(() => {
        setElapsedTime((prevElapsedTime) => prevElapsedTime + 100);
        updateGlobalData("mouseDownTime", elapsedTime + 100); 
      }, 100);

      return () => clearInterval(intervalId);
    }
  }, [mouseDownTimeStamp, elapsedTime]);

  useEffect(() => {
    updateGlobalData("mouseDownTime", elapsedTime); 
  }, [elapsedTime]);

  return (
    <  >   
      <CanvasSettings />
      <CanvasEditor />
      <Timeline />
    </>
  );
};

package.json
{
  "name": "mapping-software",
  "version": "0.1.0",
  "private": true,
  "configurations": [
    {
      "name": "Next: Chrome",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "sourceMapPathOverrides": {
        "webpack:///./*": "${webRoot}/*"
      }
    }
  ],
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/react": "^11.11.1",
    "@emotion/styled": "^11.11.0",
    "@mui/material": "^5.14.18",
    "@mui/system": "^5.14.18",
    "@preact/signals": "^1.2.1",
    "file-saver": "^2.0.5",
    "html2canvas": "^1.4.1",
    "jszip": "^3.10.1",
    "next": "14.0.0",
    "react": "^18",
    "react-dom": "^18",
    "react-dropzone": "^14.2.3",
    "uuidv4": "^6.2.13"
  },
  "devDependencies": {
    "@types/file-saver": "^2.0.7",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "@types/tinycolor2": "^1.4.6",
    "@wixc3/react-board": "^2.3.0",
    "autoprefixer": "^10",
    "eslint": "^8",
    "eslint-config-next": "14.0.0",
    "postcss": "^8",
    "postcss-preset-env": "^9.2.0",
    "tailwindcss": "^3.3.5",
    "typescript": "^5"
  }
}

我描述的行为仅发生在时间线内。 value.map 块。外面的每个按钮都有效。此外,当我注释掉这个块时,它也开始工作:

useEffect(() => {
    // Add event listeners when the component mounts
    document.addEventListener("mousedown", handleMouseDown);
    document.addEventListener("mouseup", handleMouseUp, true);

    // Remove event listeners when the component unmounts
    return () => {
      document.removeEventListener("mousedown", handleMouseDown);
      document.removeEventListener("mouseup", handleMouseUp, true);
    };
  }, []);
reactjs next.js onclick onclicklistener
1个回答
0
投票

出于某种原因,当我删除 uuidv4 作为 keyprop 时,删除按钮开始工作

{timeline.value.map((imageDataURL, index) => (
      <div
        className="relative border-2"
        key={index} // changed uuidv4() for index
        style={{
          border: "black 1px solid",
          width:  (timelineImageSize),
          height:  (timelineImageSize),
        }}
      >
        <button
          onClick={(e) => handleDeleteImage(index, e)}
          className="z-50  absolute top-0 right-0 p-2 bg-red-500 text-white rounded-md cursor-pointer"
        >
          Delete
        </button>

        <img
          src={imageDataURL}
          width={timelineImageSize}
          height={timelineImageSize}
          alt={`Image ${index}`}
        />
        <IndexLabel
          label={(index + 1).toString()}
          customClasses="absolute top-0 left-0 text-lg"
        />
      </div>
    ))}
© www.soinside.com 2019 - 2024. All rights reserved.