How to display an image with <img> from Mongoose using React front-end How to display an image with <img> from Mongoose using React front-end mongoose mongoose

How to display an image with <img> from Mongoose using React front-end


There are a couple libraries you could use, but I will arbitrarily select Axios for a demonstration. It sounds good if the images are already in Mongo DB.

Your objective is to get photos from the server to the client, so you need a function to get them on demand. You could also investigate fetch or request.

Axios: https://www.npmjs.com/package/axios

In React, try something like this

  async getPhotos() {    const res = await Axios.get('/photos')    console.log('RESPONSE', res)    const photos = res.data    console.log('IMAGES', photos)    this.setState({ photos })  }

Here is a more complete example

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>    )  }}

Citation: In React.js should I make my initial network request in componentWillMount or componentDidMount?

If you want to fetch one more photo after, you should try to think immutably and replace the this.state.photos Array with a duplicate of itself plus the new image pushed onto the end of the array. We will use the spread operator for this to do a shallow copy on the existing photos Array. This will allow React to diff against the two states and efficiently update for the new entry.

const res = await Axios.get('/photo?id=1337')const photo = res.datathis.setState({  photos: [...photos, photo]})

Note: the secret trick is to avoid ever doing this.state.photos.push(photo). You must place an illegal sign on setting state like that.

In React, try to consider a way you can get an Object or Array. Once you have it in your mind, throw it into a Component's state. As you progress into Redux, you will end up storing items sometimes in the Redux store. That is too complex and unnecessary to describe now. The photos would be available perhaps as this.props.photos via the Redux Connect Function.

For most other times, a Component's state field is an excellent place to store anything of interest to a Component.

You can imagine it like a holder at the top of the Component.