javascript - 如何在反应中折叠子组件中的手风琴
问题描述
我正在创建一个页面来更新我正在使用 NextJS 构建的电子商务网站上的产品详细信息,并且我将图像上传部分嵌套在单个项目页面的手风琴内。上传图片后,我想清除上传表单并关闭手风琴。它正在关闭我遇到问题的手风琴。
ImageUploadAccordion.js:
import React, {useRef} from 'react';
import {Accordion} from 'react-bootstrap'
import ImageUpload from './ImageUpload'
export default function ImageUploadAccordion({ item }) {
const accordionRef = useRef(null);
const toggleAccordion = () => {
accordionRef.current.click();
}
return (
<Accordion ref={accordionRef} defaultActiveKey="0">
<Accordion.Item eventKey="1">
<Accordion.Header>
<span className="btn btn-outline-success">Upload Images</span>
</Accordion.Header>
<Accordion.Body>
<ImageUpload
toggle={toggleAccordion}
item={item}
/>
</Accordion.Body>
</Accordion.Item>
</Accordion>
)
}
图片上传.js:
import React, {useState} from 'react';
import { useRouter } from 'next/router'
export default function ImageUpload({ item, toggle }) {
const router = useRouter()
const [images, setImages] = useState([])
const [imageURLS, setImageURLS] = useState([])
const [tags, setTags] = useState([])
const [theInputKey, setTheInputKey] = useState('')
const uploadImageToClient = (event) => {
if (event.target.files && event.target.files[0]) {
setImages((imageList) => [...imageList, {"index": images.length, "data": event.target.files[0]}]);
setImageURLS((urlList) => [
...urlList,
URL.createObjectURL(event.target.files[0])
]);
}
let randomString = Math.random().toString(36);
setTheInputKey(randomString)
};
const uploadTagToClient = (e) => {
if (event.target.value) {
const name = e.target.getAttribute("name")
// const i = event.target.value;
// document.getElementById("image-upload")
setTags((tagList) => [...tagList, {"name": name, "tag": e.target.value}]);
}
};
const removeImage = (name) => {
// debug
alert(`Trying to remove image index ${name}`)
let newImages = []
let newTags = []
setImages(images.filter(image => image.data.name !== name));
setTags(tags.filter(tag => tag.name !== name));
}
const uploadToServer = async (e) => {
const body = new FormData()
images.map((file, index) => {
body.append(`file${index}`, file.data);
});
// Use the filenames as keys then we can retrieve server side once we have the images
tags.map((tag, index) => {
body.append(tag.name, tag.tag)
})
const response = await fetch("/api/file", {
method: "POST",
"Content-Type": "multipart/form-data",
body
})
var message = await response.json();
alert(message['message'])
setImages([])
setTags([])
toggle()
};
const openImageUploadDialogue = () =>{
document.getElementById("image-upload").click()
}
return (
<div className="container">
<input style={{display:'none'}} accept="image/*" id="image-upload" type="file" key={theInputKey || '' } className="btn btn-outline-success-inverse" onChange={uploadImageToClient} />
<button className="btn btn-outline-success-inverse" onClick={openImageUploadDialogue} >
Add Image
</button>
<hr className = "text-pink"/>
<div className="row">
<div className="col d-flex flex-wrap">
{images.map((file, index) => {
return (
<div className="div p-1" key={file.data.name}>
<p className="text-pink">{file.data.name}</p>
<p>Tag</p>
<input type="text" name={file.data.name} id={`${file.data.name}`} onChange={uploadTagToClient} />
<img src={imageURLS[index]} height="200" width="150" />
<div className="btn btn-outline-success-inverse" onClick={ () =>removeImage(file.data.name)}>Remove Image</div>
</div>
);
})}
</div>
<button
className="btn btn-outline-success-inverse"
type="submit"
onClick={uploadToServer}
>
Upload Images
</button>
</div>
</div>
);
}
根据类似问题的另一个答案,我尝试使用 useRef 创建对手风琴的引用,以及使用此引用来激活单击事件的函数,该函数已传递给 ImageUpload 组件,但它似乎不起作用我不确定为什么。
任何帮助总是很感激:-)
解决方案
我相信你有错误的目标ref
,更新它以定位自动生成的按钮来包装标题内容。
<h2 class="accordion-header"><button type="button" aria-expanded="true" class="accordion-button"><span class="btn btn-outline-success">Upload Images</span></button></h2>
基本示例:
export default function ImageUploadAccordion({ item }) {
const accordionRef = useRef(null);
const toggleAccordion = () => {
accordionRef.current.querySelector('button').click();
}
return (
<Accordion defaultActiveKey="0">
<Accordion.Item eventKey="1">
<Accordion.Header ref={accordionRef}>
<span className="btn btn-outline-success">Upload Images</span>
</Accordion.Header>
<Accordion.Body>
<ImageUpload
toggle={toggleAccordion}
item={item}
/>
</Accordion.Body>
</Accordion.Item>
</Accordion>
)
}
推荐阅读
- python - 我可以使用类或列表来提高我的代码效率吗?
- .net-core - 实体框架核心导航属性和连接,正确的模式
- python - FastAPI 在子进程中从 websocket 发送
- python - 熊猫的负时差
- javascript - 如何停止调度请求操作?
- c++ - 从文本文件中求和逗号分隔的整数,然后存储到 C++ 中的数组中
- android - 后退按钮总是转到主页片段,也弹出对话框片段
- mongodb - 将图像保存到 mongodb
- javascript - 如何通过 updateMany 正确更新 Mongodb 中的所有数据?
- salesforce - 集成 Salesforce 与 Docusign 无效类型:dfsle.Envelope