提问人:ribert 提问时间:8/11/2023 更新时间:8/11/2023 访问量:49
在 NextJS 中添加保存逻辑后未触发更改输入
on change input not fired after adding a save logic in nextjs
问:
添加保存逻辑后不会触发 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>`
答: 暂无答案
评论