node.js - 如何使用 React 前端显示来自 Mongoose的图像
问题描述
最终目标:让用户上传图片(小于16mb,因此无需担心Grid FS),通过Mongoose将该图片存储在我的Mongodb数据库中,并使用该属性将图片显示在屏幕上。
要上传文件,我使用 Multer 并将其添加到数据库中,如下所示:
newItem.picture.data = Buffer(fs.readFileSync(req.file.path), 'base64');
newItem.picture.contentType = 'image/png';
并且似乎成功添加到了mongodb。看起来像这样: 图像如何出现在 mongodb
我能够从我的前端发送一个 get 请求,当我 console.log 它时,这就是我得到的:Data after being retreived from database。现在的问题是,如何将其添加到属性并在屏幕上显示图像。谢谢!
编辑:主持人将问题标记为过于宽泛。很公平,我不太确定如何处理它。由于我能够解决它,这就是我的前端的样子。
componentDidMount() {
const PATH = "http://localhost:8080/apii/items/getitems";
axios.get(PATH)
.then(res => {
let picture64Bit = res.data[0].data.data
picture64Bit = new Buffer(x, 'binary').toString('base64');
this.setState({picture: picture64Bit})
})
.catch(err => console.log(err))
}
这里的关键是,1) res.data[0].data.data 等于那个随机的数字列表。我把它转换回base64,所以它看起来和上面第一张来自mongodb的图片完全一样。然后,在 img 属性中内联显示它非常简单:
<img src = {`data:image/png;base64,${this.state.picture}`} />
解决方案
您可以使用几个库,但我会随意选择Axios
进行演示。如果图像已经在 Mongo DB 中,这听起来不错。
您的目标是从服务器获取照片到客户端,因此您需要一个函数来按需获取它们。您也可以调查fetch
或request
。
Axios:https ://www.npmjs.com/package/axios
在 React 中,尝试这样的事情
async getPhotos() {
const res = await Axios.get('/photos')
console.log('RESPONSE', res)
const photos = res.data
console.log('IMAGES', photos)
this.setState({ photos })
}
这是一个更完整的例子
import React, { Component } from 'react'
import Axios from 'axios'
class List extends Component {
constructor(props) { // super props allows props to be available
super(props) // inside the constructor
this.state = {
photos : [], // Initialize empty list to assert existence as Array type
// and because we will retrieve a list of jpegs
error: '', // Initialize empty error display
}
}
componentDidMount() {
this.getPhotos() // Do network calls in componentDidMount
}
async getPhotos() {
try {
const res = await Axios.get('/photos')
console.log('RESPONSE', res)
const photos = res.data
console.log('IMAGES', photos)
this.setState({ photos, error: '' })
} catch (e) {
this.setState({ error: `BRUTAL FAILURE: ${e}` })
}
}
render() {
if (error.length) {
return (
<div>{this.state.error}</div>
)
}
if (!photos.length) {
return (
<div>No photos yet</div>
)
}
// Assuming shape { id: 0, caption: 'Cats again', src: 'http://www.com/win.jpg' }
// Make sure to include key prop when using map (for state management)
return (
<ul>
{this.state.photos.map(photo => (
<li key={photo.id} style={{ position: 'relative' }}>
<span>{photo.caption}</span>
<img src={photo.src}
<div
className="overlay"
style={{
position: 'absolute'
width: '100%',
height: '100%',
}}
/>
</li>
))}
</ul>
)
}
}
引用:在 React.js 中,我应该在 componentWillMount 还是 componentDidMount 中发出我的初始网络请求?
如果您想在之后再获取一张照片,您应该尝试不可变地思考并将this.state.photos
数组替换为自身的副本以及推送到数组末尾的新图像。为此,我们将使用扩展运算符对现有照片数组进行浅拷贝。这将允许 React 区分这两种状态并有效地更新新条目。
const res = await Axios.get('/photo?id=1337')
const photo = res.data
this.setState({
photos: [...photos, photo]
})
注意:秘诀是避免做任何事情this.state.photos.push(photo)
。你必须在这样的设置状态上放置一个非法标志。
在 React 中,尝试考虑一种获取对象或数组的方法。一旦你想到了它,就把它扔进一个组件的状态。随着您进入 Redux,有时您最终会将项目存储在 Redux 存储中。这太复杂且没有必要现在描述。这些照片也许可以this.props.photos
通过 Redux Connect Function 获得。
在大多数其他情况下,组件的状态字段是存储组件感兴趣的任何内容的好地方。
你可以把它想象成组件顶部的一个支架。
推荐阅读
- hyperledger-fabric - 无法在 Fabric v1.4 上使用客户端身份链代码库实例化 Go 链代码
- javascript - 如何在将参数添加到 url 之前检查参数
- javascript - 从嵌套对象创建元素。(反应)
- c# - WPF 样式不适用于所有控件
- python - Pandas 将多个数据帧与存储在多个列上的查找值合并
- python - 根据其内容以自定义顺序对 python 数组进行排序
- java - 将 JDateChooser 作为渲染添加到 JTable
- javascript - 在 HTML h1 标记之前处理 JavaScript
- javascript - 如何使用带有scrollTop的gsap Draggable进行过度滚动?
- sparql - DBpedia 有括号时不显示结果