0

My app uses React.js and Node.js for backend. When the page is loaded all images are rendered sucessfully but when refreshing the page sometimes some images are not loaded. So this issue is inconsistent and affects random images when it happens.

Using Multer the application initially saves the images to local a folder (src/assets/uploaded_imgs) then saves in database the img path (for each entity). Using Axios the entities are obtained from DB through a custom hook, saved to a State and then mapped and rendered on the component.

The problem is being caused by the following structure I'm using:

const list = items.map((item) => {
        return <div>
            ...
            {
                checkImg(item) ?
                    <img src={require(`../../${item.img_url}`)} alt="img cover" /> :
                    <img src='imageUnavailable.png' alt="Not provided" />
            }
            ...
        </div>
    })

If I just use the <img src={require(`../../${item.img_url}`)} alt="img cover" /> instead of the ternary conditional there are no issues when refreshing but without it if the local image is moved or deleted, the application breaks.

The checkImg function serves to check if the image is there and if it's a valid file before importing it:

const checkImg = (item) => {
        try {
            const img = new Image()
            img.src = require(`../../${item.img_url}`)
            return img.complete && img.naturalWidth !== 0
        } catch (error) {
            return false
        }
    }

The app is still in delevopment so I didn't tested this issue in deployment in case this is important.

I searched suggestions on using a service worker or a lazy loading library but it looked overkill or a too complex implementation.

Can anyone tell me how to solve this issue? Please note that if there's a better solution than this ternary conditional I'm also interested.

Thanks in advance for any help.

1 Answers1

0

A quick search led me to the suggestion in the link below, which I'm not if you've tried however I believe require is to be used only with static images and you mention storing it in a db and using the value from a saved state. Have you tried without the require. This is how I access images when using state.

<img src={item.img_url} alt="img cover" />

In react, how do I use require for an image?

technified
  • 353
  • 1
  • 2
  • 15
  • So far using require was the only method I could find to make it work considering the number of images to be rendered is dynamic. The images are static and they are stored in local a folder. The DB is holding their path and name only, to be used when importing the image. – Rafael Avant Apr 26 '23 at 17:00
  • So I can use the image like you suggested: ```img cover``` I would need to import them first. How can I do it if the number of images are variable? – Rafael Avant Apr 26 '23 at 17:08
  • Ok, that makes more sense. Try this `TESTER` This works for me every page load. – technified Apr 28 '23 at 02:01
  • 1
    That's definitely more elegant. The issue remains though. Thanks for the help anyway! – Rafael Avant Apr 28 '23 at 20:40
  • 1
    Sure. One question I forgot to ask. When debugging your checkImg function does img.complete && img.naturalWidth !== 0 always return true? Does it throw an exception and if so what is the error. That's the only place I can see that would cause an inconsistent result. – technified Apr 29 '23 at 00:39
  • You are right. It seems the issue is being caused by the condition ```img.complete```. Sometimes when refreshing the page this condition fails on some image. No idea why though. It should be consistent since is the same image. Do you have any insight? Otherwise I might have to find another method to confirm if the image is valid. Thanks for the help. – Rafael Avant Apr 30 '23 at 21:05
  • Is img.complete being obtained from the db or is there some logic to determine whether that value returns true or false? I bet if you hard coded that value to be true, the images will always load as expected. You need to figure out where the img.complete value is failing by tracing it back to the origin. You're welcome, if I've helped you enough to work through the issue and either rewrite it or correct the bug please upvote :) and good luck! – technified May 01 '23 at 01:01
  • Sorry. I'm not sure I understood what you said. `img.complete` is one of the two conditions of the checkImg function. Its intended to check if theres a valid image on the folder before importing it (not sure what you meant with hard coding its result). – Rafael Avant May 02 '23 at 15:24
  • I'm asking where img.complete value gets set. You are expecting it to be true but what determines setting it to true or false – technified May 03 '23 at 00:47
  • Oh ok. The checkImg tries to import the image and the img.complete returns true if the imported image is loaded succesfully. – Rafael Avant May 03 '23 at 21:42