React Gallery: Part Two

I recently went through some tech screens that involved building something in React while being recorded, using a browser-based live-code style IDE. You can start with Part One here.

Recap

In Part One I covered

  • Doing a close reading of the instructions/requirements
  • Planning a data model and using mock data to contruct a wireframe
  • Fetching services
  • Transforming incoming data to make it usable
  • Showing the images

Here is the final site:

Step Five: Image Loading

At the end Part One I was able to load the images into a gallery, but they load as they arrive at the browser. Our challenge requires that we detect when all the images have completely loaded before displaying them.

This will require each Image component to notify Gallery when it is done so that Gallery can monitor the situation and trigger displaying the images at the right time.

The img tag onLoad event will be triggered when the image src is fully loaded, which is exactly what we need. But we will need to trigger on 98 of these. And how will the Image component notify Gallery?

A common solution to telegraphing updates to a parent component is to put a function into a component prop. Since a function is an Object, this is perfectly fine, and is what is known as a “callback” function. We can even put an argument in the function as it is called from the child component.

In this case I created a function called handleImageLoaded that accepts a “src” argument which will be the image URL. Each Image will send it’s src attribute back to Gallery after its done loading. We can build up an array of image URLs and compare both the length and contents to the imageURL array that is in our image state each time it updates until they match. Then we can make the images visible.

It was easier and cleaner to put all of this logic in its own function and scope, which I called ImageLoadResults. It has its own state hooks for loaded images and readiness, so they are maintained separately from the data loading stage in the useEffect hook I covered in part one. How is ImageLoadResults triggered? It is the component within the Gallery return statement.

The gallery looks the same after it’s done loading, but it now satisfies the requirement to show “Loading…” and then display the images once they are done loading. Github Branch 5-loading-component

Step Six: Tooltips and Cleanup

Now to satisfy the requirement to show a hover text with the name of the breed of the dog displayed at the lower Left of each image component. This will require adding another div to the image component, 2 handler functions and a state hook.

  const [isTooltipShown, setIsTooltipShown] = useState(false);
  
  const breedNameHandleHover = () => {
    setIsTooltipShown(true);
  };

  const breedNameHandleNoHover = () => {
    setIsTooltipShown(false);
  };

The state change is triggered by an onMouseEnter and onMouseLeave on the img tag. The span containing the text is displayed conditionally:

        <span
          className="js_name"
          key={`_${index}`}
          style={{ display: isTooltipShown ? "block" : "none" }}
        >
          &nbsp;{breed}
        </span>

Cleanup:

  • Added some conditional styles to prevent the vertical scrollbar from appearing and constantly changing while the Loading… was displayed.
  • There was a case in the previous couple of branches where the page would show an error and fail to load because the length of breeds was still zero, so i added a null check to that component.
  • Some styling tweaks to ensure the pictures were proportional
  • I changed the App.test.js to pass on all but one of the branches
  • Addressed any console log warnings regarding providing a key for displaying list items.
  • Stretch goal: replace the Loading… text div with a custom spinner that shows my name.

Final Branch 6 Live:

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Captcha loading...

This site uses Akismet to reduce spam. Learn how your comment data is processed.