DoubleTri
DoubleTri

Reputation: 891

Can't render image from state in React/JSX

I'm getting the path to an image from my database. The image file is stored locally. I store the path as State for the component thus keeping the component dynamic as opposed to simply importing the path form it's location. So...

this works...

  render() {
    return (
      <div>
        <Col xs={6} md={4}>
          <Image src={require('../../../../public/uploads/file-1516414373384.png')}responsive />
        </Col>
      </div>
    )

However, this does not...

class Reports extends Component {
  constructor(props) {
    super(props);
    this.state = {
      reports: [],
      photos: null
    }
  }

  componentWillMount() {
    var reports = []
    axios.get('/uploadUserImage')
      .then( (response) => {
        response.data.forEach(function(report){
          reports.push(report)
        })
      }).then(() => {
        this.setState({reports})
      }).then(() => {
        var path = '../../../../'+this.state.reports[0].file;
        var rightPath = path.replace(/\\/g,"/");
        this.setState({photos: rightPath})
      })
      .catch( (error) => {
        console.log(error);
      });
  }

  render() {
    return (
      <div>
        <Col xs={6} md={4}>
          <Image src={require(this.state.photos)}responsive />
        </Col>
      </div>
    )

Even though the second non-working code compiles to the same this as the first working bit of code.

I get an error that says

  Uncaught Error: Cannot find module "."

So maybe there is something wrong in my web-pack? but if that were true wouldn't both cases throw the error???

I also tried template literals...

<Image src={require(`${this.state.photos}`)}responsive />

As was the answer to a similar question, but no dice - Same error.

Upvotes: 1

Views: 1526

Answers (3)

Michael
Michael

Reputation: 1

I was running into a similar issue and found this to work in my project:

  import React, { Component } from 'react';

    class ImageUpload extends Component {
      constructor(props) {
       super(props);
       this.state = {
       file: null
     };
     this.handleChange = this.handleChange.bind(this);
     }
    handleChange = e => {
     this.setState({
     file: URL.createObjectURL(e.target.files[0])
    });
    };

   render() {
   const fileAttached = this.state.file;
   return (
     <div>
        <input type="file" onChange={this.handleChange} />
        {fileAttached ? (
           <img
              src={this.state.file}
              alt="File Uploaded"
              height="300"
              width="400"
           />
          ) : (
           <img src="" alt="No file uploaded" />
        )}
       </div>
    );
 }

}

export default ImageUpload;

Upvotes: -1

DoubleTri
DoubleTri

Reputation: 891

It’s OP. I tried everything suggested here and in other similar questions. Nothing worked. I installed react-image and now everything works fine.

Wish I could give an explanation as to what’s going on under the hood, and what exactly went wrong before, but I don’t really know. Images do render now via component state. So, victory I guess.

Upvotes: 1

Mayank Shukla
Mayank Shukla

Reputation: 104529

I think, this is because first time it trying to import image of path null (initial value of the path in state), only after getting successful response from server, it will have the correct image path.

One possible solution is, render the image only when you have a valid path means after getting response, Use conditional rendering and put the check.

Like this:

{this.state.photos ? <Image src={require(this.state.photos)} responsive /> : null}

Upvotes: 1

Related Questions