DEV Community

Cover image for React: Switch background images when they are ready
Red Ochsenbein (he/him)
Red Ochsenbein (he/him)

Posted on • Edited on • Originally published at ochsenbein.red

3 2

React: Switch background images when they are ready

In an application I'm currently working on I needed a way to make sure the image is actually loaded before I put it into the background. How did I do that?

Actaully it's pretty simple: Create an image object, load the image - which then would be put into the cache - and when the image object sends the load event switch the image.

import React, { PropsWithChildren, useCallback, useState } from 'react'
import styled from 'styled-components'

import useWsMessage from '../hooks/useWsMessage'

interface BackgroundData {
  credits?: string
  url: string
}

const Background: React.FC<PropsWithChildren> = ({ children }) => {
  const [current, setCurrent] = useState<BackgroundData | null>(null)

  const handleMesssage = useCallback((event: MessageEvent<string>) => {
    const raw = event.data.replace('SetBackground ', '')
    try {
      const background: BackgroundData = JSON.parse(raw)
      const img = new Image()
      img.src = background.url
      img.onload = () => setCurrent(background)
    } catch {
      // do nothing
    }
  }, [])

  useWsMessage('SetBackground', handleMesssage)

  return (
    <BackgroundRenderer url={current?.url}>
      {children}
    </BackgroundRenderer>
  )
}

interface BackgroundRendererProps {
  url?: string
}

const BackgroundRenderer = styled.div.attrs<BackgroundRendererProps>(({ url }) => {
  return {
    style: { backgroundColor: 'black', ...(url ? { backgroundImage: `url(${url})` } : {}) },
  }
})<BackgroundRendererProps>`
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  bottom: 0;
  height: 100%;
  left: 0;
  position: fixed;
  right: 0;
  top: 0;
  width: 100%;
`

export default Background
Enter fullscreen mode Exit fullscreen mode

As you can see the component retrieves a message from websocket and uses the URL to set the background image. The important part is this:

const img = new Image()
img.src = background.url
img.onload = () => setCurrent(background)
Enter fullscreen mode Exit fullscreen mode

It creates an image object, sets the src and sets the background image state as soon as the image is loaded.

That's it. Pretty simple, huh? I hope this helps someone having a similar problem in the future.

Sentry mobile image

App store rankings love fast apps - mobile vitals can help you get there

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read full post →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay