【发布时间】:2020-12-15 07:12:20
【问题描述】:
我正在尝试:
- 将图片上传到 Firebase 存储
- 在 Firestore 中的“文章”文档下创建字段“fileUrl”
- 引用 Firestore 中的文档,以便每张图片都知道它分配给了哪篇文章。
我设法以某种方式完成了所有这些工作,但问题是,当我提交带有标题、内容和图像的表单时,它会在 Firestore 中创建一个只有图像('fileUrl')的新文档,而不是创建包含表单其余数据的文档。
我知道这可能是因为我在 UploadFile.js 中创建了一个新文档,但是如何将 UploadFile.js 中创建的字段与 AddArticle.js 中的字段连接起来?
我还收到“未处理的拒绝(TypeError):无法读取此行的未定义的属性“状态”:
firebase.firestore().collection('articles').doc(this.state.documentId).update({
fileUrl: fileUrl
})
上传文件.js
import React from "react";
import firebase from '../Firebase';
function UploadFile() {
const [fileUrl, setFileUrl] = React.useState(null);
const onFileChange = async (e) => {
const file = e.target.files[0]
const storageRef = firebase.storage().ref()
const fileRef = storageRef.child(file.name)
await fileRef.put(file);
setFileUrl(await fileRef.getDownloadURL().then(fileUrl => {
firebase.firestore().collection('articles').doc(this.state.documentId).update({
fileUrl: fileUrl
})
.then(() => {
setFileUrl('')
})
} ));
};
return (
<>
<input type="file" onChange={onFileChange} />
<div>
<img width="100" height="100" src={fileUrl} alt=''/>
</div>
</>
);
}
export default UploadFile;
AddArticle.js
import React, { Component } from 'react';
import firebase from '../Firebase';
import UploadFile from '../components/UploadFile';
class AddArticle extends Component {
constructor() {
super();
this.ref = firebase.firestore().collection('articles');
this.state = {
title: '',
content: '',
fileUrl: ''
};
}
onChange = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
onSubmit = (e) => {
e.preventDefault();
const { title, content, fileUrl } = this.state;
this.ref.add({
title,
content,
fileUrl
}).then((docRef) => {
this.setState({
title: '',
content: '',
fileUrl: '',
documentId: docRef.id
});
this.props.history.push("/")
})
.catch((error) => {
console.error("Error adding document: ", error);
});
}
render() {
const { title, content, fileUrl } = this.state;
return (
<div className="container">
<br></br><br></br><br></br>
<div className="panel panel-default">
<div className="panel-heading">
<h3 className="panel-title text-center">
Create a new article
</h3>
</div>
<br></br><br></br>
<div className="panel-body">
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label for="title">Title:</label>
<input type="text" className="form-control" name="title" value={title} onChange={this.onChange} placeholder="Title" />
</div>
<div className="form-group">
<label for="content">Content:</label>
<textArea className="form-control" name="content" onChange={this.onChange} placeholder="Content" cols="80" rows="20">{content}</textArea>
</div>
{/* <input type="file" onChange={this.onFileChange} /> */}
<UploadFile onChange={this.onChange} value={fileUrl}/>
<button type="submit" className="btn btn-success">Submit</button>
</form>
</div>
</div>
</div>
);
}
}
export default AddArticle;
【问题讨论】:
-
您的代码流程如何?哪个是顺序,是先创建文章还是上传图片?还是两个动作同时触发?
-
嗨,我们的想法是让文本字段和上传图像采用相同的形式,并同时创建所有内容,但我无法在 AddArticle.js 中使用异步,因为 AddArticle.js是一个类,这就是为什么我将它放在不同的文件中并在文本字段下方的表单中调用组件的原因。我不确定这是否是个好主意。有没有更好的方法来做到这一点的例子?
标签: reactjs firebase file-upload google-cloud-firestore firebase-storage