我正在将该图像的图像和标题上传到 firebase。我制作了一个自定义钩子(useStorage),用于上传该图像的图像和标题。我有两个单独的组件 UploadForm 和 ProgressBar,我将标题和选定的图像和标题从 UploadForm 传递到 ProgressBar。我可以在 firestore 中为图像和标题创建字段,图像正在上传但标题字段仍为空字符串。
我正在附上 3 个文件的代码,任何帮助将不胜感激。
import { useState, useEffect } from 'react';
import { projectStorage, projectFirestore, timestamp } from '../firebase/config';
const useStorage = (file) => {
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
const [url, setUrl] = useState(null);
const [title, setTitle] = useState('');
useEffect(() => {
// references
const storageRef = projectStorage.ref(file.name);
const collectionRef = projectFirestore.collection('images');
storageRef.put(file).on('state_changed', (snap) => {
let percentage = (snap.bytesTransferred / snap.totalBytes) * 100;
setProgress(percentage);
}, (err) => {
setError(err);
}, async () => {
const url = await storageRef.getDownloadURL();
const createdAt = timestamp();
await collectionRef.add({ url, createdAt, title });
setUrl(url);
setTitle(title);
});
}, [file, title]);
return { progress, url, error, title };
}
export default useStorage;
import React, { useState } from 'react';
import ProgressBar from './ProgressBar';
const UploadForm = () => {
const [file, setFile] = useState(null);
const [error, setError] = useState(null);
const [header, setHeader] = useState('')
const types = ['image/png', 'image/jpeg'];
const handleChange = (e) => {
let selected = e.target.files[0];
if (selected && types.includes(selected.type)) {
setFile(selected);
setError('');
} else {
setFile(null);
setError('Please select an image file (png or jpg)');
}
};
return (
<form>
<label>
<input type="file" onChange={handleChange} />
<span>+</span>
</label>
<input placeholder="Enter title for pic..." type="text" name={header} onChange={(e)=> setHeader(e.target.value)} />
<div className="output">
{ error && <div className="error">{ error }</div>}
{ file && <div>{ file.name }</div> }
{ file && <ProgressBar file={file} setFile={setFile} header={header} /> }
</div>
</form>
);
}
export default UploadForm;
import React, { useEffect } from 'react';
import useStorage from '../hooks/useStorage';
import { motion } from 'framer-motion';
const ProgressBar = ({ file, setFile, header }) => {
const { progress, url, title } = useStorage(file);
useEffect(() => {
if (url) {
setFile(null);
}
}, [url, setFile]);
return (
<motion.div className="progress-bar"
initial={{ width: 0 }}
animate={{ width: progress + '%' }}
></motion.div>
);
}
export default ProgressBar;
答案 0 :(得分:1)
useStorage
有一个 [title, setTitle]
钩子用于
await collectionRef.add({ url, createdAt, title });
setUrl(url);
setTitle(title);
但问题是标题是空的。你从不设置标题。您将 header
传递给进度条,但您不使用它。您应该更新 useStorage 的两个参数:file 和 header 并调用 useStorage(file, header)
将 useStorage 签名更新为 const useStorage = (file, header) => {}
在 useStorage 中,您可以更新 const [title, setTitle] = useState(header)
答案 1 :(得分:0)
据我所知,您永远不会从任何地方获得 title
。您所做的就是将使用 title
初始化的状态变量 ''
发送到 Firestore,然后将 setTitle
发送到相同的空字符串 title
。
您的意思是将 header
与 file
一起传递到您的钩子中吗?