2
\$\begingroup\$

React beginner here. I'm practicing state and hooks, and I wanted to create a small app that every two seconds fetches an image URL from a service (that returns random images) and shows the returned image.

The idea is to make it simple and readable. Do you have any suggestions?

import React, { useState, useEffect } from 'react';

function App() {
  const [imageUrl, setImageUrl] = useState("");

  useEffect(() => {
    const delay = imageUrl ? 2000 : 0;

    new Promise(resolve => setTimeout(resolve, delay)).then(() => {
      fetch("https://dog.ceo/api/breeds/image/random")
        .then(res => res.json())
        .then(data => setImageUrl(data.message))
        .catch(err => console.log("Problemino!", err))
    });
  }, [imageUrl]);

  return(
    <div>
      <img src={imageUrl} alt="Random doggo!" />
    </div>
  );
}

export default App;

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

With readability in mind: I'd avoid the unnecessary promise wrapper and promise chaining, and take the async/await approach instead. It flattens the code and I find it easier to follow.

Your useEffect would look something like this after refactoring:

useEffect(() => {
  const delay = imageUrl ? 2000 : 0;

  setTimeout(async () => {
    try {
      const res = await fetch("https://dog.ceo/api/breeds/image/random");
      const data = await res.json();
      setImageUrl(data.message);
    } catch (e) {
      console.error("Problemino!", e);
    }
  }, delay);
}, [imageUrl]);

One thing to note: if there's an error, setImageUrl won't be called, and so the image will stop updating. This is because the imageUrl dependency for useEffect won't have changed. This is true in your original code too. I'd recommend better error handling to ensure that it keeps retrying.

P.s. I thoroughly enjoyed viewing dog pictures whilst looking into this :D

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.