上传到firebase存储.我的应用程序在点击表单提交按钮时上传了两次文件



所以这是我的问题。我正试图将一个文件上传到firebase存储,但每次我点击上传,由于某些原因,文件都会上传两次。我正在使用react,并创建了一个自定义挂钩来处理上传到firebase的操作。我正在使用react bootstrap来获得我需要发送的数据。有一个照片文件,一个输入文本和一个选择。这是我的自定义挂钩:

const UseStorage = (file) => {
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
const [url, setUrl] = useState(null);

useEffect(() => {
const storageRef = ref(storage, `images/${Date.now()}-${file.name}`);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on('state_changed', 
(snapshot) => {
const percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
setProgress(percentage);
}, 
(error) => {
setError(error);
}, 
async () => {
const url =  await getDownloadURL(uploadTask.snapshot.ref);
//console.log('File available at', url);
setUrl(url);
});
}, [file]);
return {progress, error, url }
}
export default UseStorage;

这是我处理数据的组件:

export default function AddItem( {showModal, handleClose} ) {
// data to send to firebase
const [data, setData] = useState(null);
//ref of the modal input
const refName = useRef();
const refFile = useRef();
const refCategory = useRef();
// error state
const [errorFile, setErrorFile ] = useState(null)
const types = ['image/png', 'image/jpeg'];
const handleSubmit = (e) => {
e.preventDefault();
if (refName.current.value === ''){
setData(null);
setErrorFile("Name can't be empty");
return;
}
if (refCategory.current.value === '') {
setData(null);
setErrorFile("Category can't be empty");
return;
}
let selectedFile = refFile.current.files[0];
if (selectedFile && types.includes(selectedFile.type) ){
setData({
file:selectedFile,
name: refName.current.value,
category: refCategory.current.value
});
setErrorFile('');
}
else {
setData(null);
setErrorFile('Please select an image file (png or jpeg).')
}
};
return (
<>
<Modal show={showModal} onHide={handleClose} backdrop="static">
<Modal.Header closeButton>
<Modal.Title>Add Item</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
<Form.Label>Name</Form.Label>
<Form.Control
type="text"
required
ref={refName}
/>
</Form.Group>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>Photo</Form.Label>
<Form.Control type="file" ref={refFile}/>
</Form.Group>
<Form.Label>Category</Form.Label>
<Form.Select aria-label="Default select example" ref={refCategory}>
<option value="Saiyajin">Saiyajin</option>
<option value="Namek">Namek</option>
<option value="Ennemy">Ennemy</option>
<option value="Cyborg">Cyborg</option>
</Form.Select>
<Button className="mt-3" variant="primary" type="submit">
Add
</Button>
</Form>
</Modal.Body>
{errorFile && <Alert variant="danger">{errorFile} </Alert>}
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Cancel
</Button>
</Modal.Footer>
{data && <ProgressBarCustom data={data} setData={setData} /> }
</Modal>
</>
)
}

这是我的customProgressBar组件,它使用自定义挂钩:

const  ProgressBarCustom = ( {data, setData} ) => {
const { progress, url } = UseStorage(data.file);
useEffect(() => {
if(url){
setData(null);
}
},[url, setData]);
console.log(progress, url)
return (
<ProgressBar now={progress} />
)
}
export default ProgressBarCustom;

不管出于什么原因,我的文件最终以两个不同的名称上传到了存储器上两次(因为我使用Date.now((创建了存储器引用(。我尝试过使用ref和state,结果也出现了同样的行为,但如果我在组件handleSubmit((方法中直接移动所有自定义挂钩上传过程,上传就可以了,我只根据需要上传一次。有人知道我做错了什么吗?感谢

尝试从index.js:中删除React.StrictMode

索引.js(删除之前(:

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

索引.js(删除后(:

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<App />
);

希望这对你有帮助!

最新更新