Check Image URL before updating State in React/Next

Asked

Viewed 49 times

0

The logic below is: React/Nextjs with Styled-Components.

Hello, I have a component that "renders" the banner of a blog (background-image), the url comes from a state that already has a standard image.

const [blogBanner, setBlogBanner] = useState('/images/imageBlogDefault.png')

But before the component receives that state, the code checks whether that blog already has a banner defined by the user. If yes, then take the url and update the state.

if (props.blog.image) {
    setBlogBanner(`${hlp.BACKEND_HOST}/images/blogBanners/${props.blog.image}`)
}

And in Styled-Components I use the background-image: url(blogBanner).

The problem is that the request that picks up the blogs returns only the url of the banner and not the image itself, so if for some reason the image is deleted from the database without removing its url on the blog... when loading this blog my code will "understand" that that blog "has image" and will update the state with the new url.

So what I need to do is not only check if it has a url (as I already do), I need to check if that url returns an image before updating the state, but I don’t know how to do that. It could even be with css (Styled-Component) if it were possible.

  • I tried to do a function that makes a request get with the image url and if the returned status is 404 then it doesn’t update the state, but it didn’t work. --> async Function test(url) { const Response = await fetch(url) console.log(Response) if (Response.status == 200) { setBlogBanner(/** Updates banner*/) } } if (props.portfolios.images[0]) { test(bannerURL) }

1 answer

1

You can try to create an object of Image to check if it is possible to load the image.

The idea is that you create the object and use the methods onload() and onerror() to check whether it was possible or not to upload the image, if possible, you update the state blogBanner, otherwise keeps the image standard (or applies some other treatment suitable for your application).

Your code could be something similar to this:

if (props.blog.image) {
  // Pegando a URL para imagem
  const url = `${hlp.BACKEND_HOST}/images/blogBanners/${props.blog.image}`;
  // Criando um objeto Image
  var img = new Image();
  img.src = url;
  // Se foi possível carregar a imagem
  img.onload = () => {
    console.log("Essa imagem ainda existe no seu servidor");
    setBlogBanner(url);
  };
  // Caso não seja possível
  img.onerror = () => {
    console.log("A imagem não existe mais, continuar com a img padrão");
  };
};
  • 1

    An additional note: this technique can be used for Lazy loading as well.

  • I tried this solution but whenever you set "new image()" in a component, it returns the error. Unhandled Runtime Error Typeerror: _ref is Undefined

Browser other questions tagged

You are not signed in. Login or sign up in order to post.