在 NextJS 中添加保存逻辑后未触发更改输入

on change input not fired after adding a save logic in nextjs

提问人:ribert 提问时间:8/11/2023 更新时间:8/11/2023 访问量:49

问:

添加保存逻辑后不会触发 onchange 事件,但是如果我注释保存逻辑它就可以工作了。事实上,我正在努力将文本保存在一个部分中并将图像上传到其中,但是当文本保存工作时,上传不起作用

当我更改它使用 handleClickOutside 函数保存的部分中的文本时,但是当我尝试上传图像时,它在选择后没有显示,当我安慰时,我发现这个函数没有被触发** handleImageUpload** 这里给出<input type="file" className='hidden' onChange={handleImageUpload} ></input>

这是图片上传的代码

import {useState,useEffect,useRef} from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {faCamera} from '@fortawesome/free-solid-svg-icons'

export  function imageUpload(defaultLanguageCode,index,sectionsArray,setImageData){
    const selectedImage=useRef(null);
    const selectableImage=useRef([]);
   
 

    console.log(defaultLanguageCode);

  
   
    function showUploadImage(event){
        event.stopPropagation(); // Stop event propagation
        selectedImage.current=event.target.parentElement.parentElement.children[1];
        event.target.parentElement.parentElement.children[1].click();
        
    }
    function handleImageUpload(event){
   
      console.log(event.target.files[0])
        selectedImage.current.src=URL.createObjectURL(event.target.files[0]);
   
        console.log(event.target.files[0].name)
        const image=event.target.files[0].name;
        setImageData(image);

        
       // const apiUrl = "http://wimdrive-wimapp-service.wimsolutions.net/api/website/wbsWebsiteSection/data/"+(sectionsArray[index]).id+"?key=image&value=" + image + "&code="+defaultLanguageCode;

        //fetch(apiUrl, {
          //method: "PUT",
          //headers: {
            //"Content-Type": "application/json",
            // Add any other headers if needed
         // },
          // You can also provide a request body if needed
          //body: JSON.stringify({}),
        //})
          //.then(response => response.json())
          //.then(data => {
            // Handle API response if needed
            //console.log("API response:", data);
          //})
          //.catch(error => {
            // Handle API error
            //console.error("API error:", error);
          //});
        //  console.log("uploaded succcc")
      }
   
    //console.log("yes",imageData)

    
    

     function handleMouseLeave(event){
        if(event.target.children[0])
        event.target.children[0].classList.add('invisible');
      
     }
     function handleMouseEnter(event){
        if(event.target.children[0])
        event.target.children[0].classList.remove('invisible');
     }
     function showUploadButton(){
        selectableImage.current.forEach((element)=>{
            if(element!=null){
                element.addEventListener('mouseenter',handleMouseEnter);
                element.addEventListener('mouseleave',handleMouseLeave);
            }
        })
     }

    function UploadComponent(){
        return(
            <div className="edit-image absolute bg-transparent  mt-1 rounded w-full h-full " 
            onClick={showUploadImage}
            onMouseEnter={handleMouseEnter}
            onMouseLeave={handleMouseLeave}
            >
                <FontAwesomeIcon icon={faCamera} className='pe-3 invisible' style={{fontSize:"40px",color:"black"}} />
                <input  type="file" className='hidden' onChange={handleImageUpload} ></input>
            </div>
        )
    }
    return {
        UploadComponent,
        selectableImage,
        selectedImage,
    }
}

以及包含用于保存的 editPageElement 的代码

  import { imageUpload } from "/helpers/imageUpload";
import { useEffect, useRef, useState } from "react";

export const useEditableElements = (sectionsArray,index,defaultLanguageCode, sectData,sectionIndex, siteInfos, imageData) => {
  const selectableElement = useRef({});
  
  const [editorPosition, setEditorPosition] = useState({ top: 0, left: 0 });
  const [isEditorVisible, setIsEditorVisible] = useState(false);
  const selectedElement = useRef(null);
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
  const [isMouseDown, setIsMouseDown] = useState(false);
  const [data, setData] = useState(false);
  
  const editorRef = useRef(null); //   EDITOR RELATED


  useEffect(() => {
    
    
  }, [defaultLanguageCode,sectData]);
  
 
  
 
  useEffect(() => {
    
    if (selectableElement) {
      
      Object.entries(selectableElement.current).forEach(([name, element]) => {
        element.addEventListener("click", handleElementClick);
        element.contentEditable = true;
        element.classList.add("editable-element");
      });
      
    }
  }, [index]);

  function handleElementClick(event) {
    if (
      event.target.classList.contains("editable-element") &&
      (selectedElement.current == null ||
        selectedElement.current != event.target)
    ) {
      setEditorPosition({
        x: event.currentTarget.getBoundingClientRect().left,
        y:
          event.currentTarget.getBoundingClientRect().top -
          event.currentTarget.getBoundingClientRect().height,
      });
      setIsEditorVisible(true);
      selectedElement.current = event.target;
    }
  }

  useEffect(() => {
    document.addEventListener("click", handleClickOutside);

    return () => {
      document.removeEventListener("click", handleClickOutside);
    };
  });

  function saveData(newData) {
    // Add the imageData to the newData object
    const newDataWithImage = { ...newData, image: imageData };

    setData(newDataWithImage);

    const a = {
      ...siteInfos,
      sectionIndex,
      section: {
        ...sectData,
        data: newDataWithImage,
      },
    };

    console.log("newDataWithImage:", newDataWithImage);
    console.log(defaultLanguageCode);

     if (sectData !== undefined && sectionsArray !== undefined && sectionsArray[index] !== undefined){
     const apiUrl = ("http://wimdrive-wimapp-service.wimsolutions.net/api/website/wbsWebsiteSection/updateData/"+(sectionsArray[index]).id+"?code="+defaultLanguageCode);
     console.log("apiUrl:", apiUrl);
    // PUT request headers
    const headers = {
      "Content-Type": "application/json", // Set the Content-Type to JSON
    };

    // Convert newData to JSON format
    const requestBody = JSON.stringify(newDataWithImage);

    // Perform the PUT request
    fetch(apiUrl, {
      method: "PUT",
      headers: headers,
      body: requestBody,
    })
      .then(response => {
        if (!response.ok) {
          throw new Error("Network response was not ok.");
        }
        return response.json();
      })
      .then(data => {
        // The API response data will be available here
        console.log("API response:", data);
      })
      .catch(error => {
        // Handle any errors that occurred during the API request
        console.error("Error:", error);
      });
    }
   
   }
console.log(sectData)
function handleClickOutside(event) {
  event.stopPropagation();
  if (
    !event.target.classList.contains("editable-element") &&
    !event.target.closest("#my-editor")
  ) {
    selectedElement.current = null;
   
   
     const isDataChanged = Object.entries(selectableElement.current).some(
       ([name, element]) => {
        
        if (sectData!== undefined) {
         return element.innerText !== sectData[name];

         }
         
         return false;
       }
     );

     if (isDataChanged) {
       const newData = Object.entries(selectableElement.current).reduce(
         (acc, [name, element]) => {
           acc[name] = element.innerHTML;
           return acc;
         },
         {}
       );

       saveData(newData);
     }
  }
}


  const handleMouseDown = (event) => {
    setIsMouseDown(true);
  };

  const handleMouseMove = (event) => {
    if (isMouseDown) {
      const { top, left, width, height } =
        editorRef.current.getBoundingClientRect();
      setElementPosition({
        x: event.clientX - width / 2 + "px",
        y: event.clientY - height / 2 + "px",
      });
    }
  };

  const handleMouseUp = (event) => {
    setIsMouseDown(false);
  };

  const resetSelector = () => {
    selectedElement.current = null;
  };

  return {
    selectableElement,
    handleElementClick,
    isEditorVisible,
    editorPosition,
    setIsEditorVisible,
    selectedElement,
    resetSelector,

  };
};


并将其应用于布局中

 return (
    <section ref={mySection} class="relative md:py-24 py-16">
    <div class="container">
        <div class="grid md:grid-cols-12 grid-cols-1 items-center gap-[30px]">
       
            <div  class="lg:col-span-5 md:col-span-6 editable-image-container">
      
            <UploadComponent  />
                <img src= {sectData.image}   class="rounded-md shadow dark:shadow-gray-800" alt="defaultimage"/>
                    
            </div>

            <div class="lg:col-span-7 md:col-span-6">
                <div class="ms-6">
                    
                
                    <h4  ref={(ref) => (selectableElement.current["title"] = ref)} class="my-6 md:text-3xl text-2xl md:leading-normal leading-normal font-semibold">{sectData.title}</h4>

                    <p ref={(ref) => (selectableElement.current["paragraph"] = ref)} class="text-slate-400">{sectData.paragraph}.</p>
                
                    
                </div>
            </div>
        </div>
    </div>`
JavaScript ReactJS 事件 next.js onchange

评论

0赞 ribert 8/11/2023
upppppppppppppp
0赞 Lilly 8/11/2023
也许将 onChange 更改为 onInput={handleImageUpload} 会有所帮助
0赞 ribert 8/11/2023
我试过了,但它实际上不起作用,onChange 有效,但是当注释保存功能时,我不知道为什么
0赞 ribert 8/11/2023
我尝试过异步函数,但仍然有同样的问题
0赞 Lilly 8/11/2023
那么,也许问题出在这行代码上: // console.log(“uploaded succcc”);把它放在这里:console.log(“API response:”, data);控制台.log(“已上传 succcc”)

答: 暂无答案