Inter 🌐 Media

  • Home
  • Blog
  • Portfolio
  • Services
  • Contact

Inter 🌐 Media

  • Home
  • Blog
  • Portfolio
  • Services
  • Contact

The window object, React hooks, and GatsbyJS

December 29th, 2019

6 minute read 📗
  • Link to The window object, React hooks, and GatsbyJS podcast on anchorfm

This past Friday I added a Crisp chat box to interglobalmedianetwork.com. Afterwards, I visited the website on mobile, and noticed that my ScrollUpButton was not well positioned as a result of the new chat box when the browser window was < 560px wide.

This really bothered me, and I wanted to fix it. The problem was, however, that I use inline styling inside the ScrollUpButton component and didn’t know how I could add media queries to inline styling in React.

In my regular JSX, I use styled-components and am able to add media queries to those styles easily and in the same way as I would in CSS or SCSS. But inline styles inside a component element is another story.

I started googling for answers, and came across the following very interesting solution:

  • React inline styles and media queries using a custom React Hook

I haven’t had the time or chance to get too much into React hooks, so I found this opportunity to use them in this instance very exciting!

Based on the article, I came up with the following re-usable hook called useMediaQuery which I stored in a folder called hooks in my src folder and placed the hook in a file called mediaQueryHooks.js:

import {useEffect, useState} from 'react'
import {window} from 'browser-monads'

export const useMediaQuery = query => {
    const mediaMatch = window.matchMedia(query)
    const [matches, setMatches] = useState(mediaMatch.matches)

    useEffect(() => {
        const handler = e => setMatches(e.matches)
        mediaMatch.addListener(handler)
        return () => mediaMatch.removeListener(handler)
    })
    return matches
}

Then I imported the hook into my Footer.js component and my index.js home page:

// Footer.js
import {useMediaQuery} from '../../hooks/mediaQueryHooks'

// index.js
import {useMediaQuery} from '../hooks/mediaQueryHooks'

I used the hook in Footer.js:

const styles = {
    container: (notRightMargin, marginBottomLess) => ({
        background: 'transparent',
        outline: 'none',
        marginBottom: marginBottomLess ? '3rem' : '3.75rem',
        marginRight: notRightMargin ? '-0.25rem' : '0.5rem',
    }),
}

const Footer = () => {
    const notRightMargin = useMediaQuery('(max-width: 559px)')
    const marginBottomLess = useMediaQuery('(max-width: 559px)')
    return (
    ...
    <ScrollUpButton
    style={styles.container(notRightMargin, marginBottomLess)}
    ContainerClassName="ScrollUpButton__Container"
    />
    ...
    )
}

as well as index.js:

const styles = {
    container: (notRightMargin, marginBottomLess) => ({
        background: 'transparent',
        outline: 'none',
        marginBottom: marginBottomLess ? '3rem' : '3.75rem',
        marginRight: notRightMargin ? '-0.25rem' : '0.5rem',
    }),
}

const IndexPage = props => {
    ...
    const notRightMargin = useMediaQuery('(max-width: 559px)')
    const marginBottomLess = useMediaQuery('(max-width: 559px)')
    return (
    ...
    <ScrollUpButton
    style={styles.container(notRightMargin,marginBottomLess)}
    ContainerClassName="ScrollUpButton__Container"
    />
    ...
    )
}

Then I ran

npx gatsby develop

and everything rendered as it should in the browser window when it was < 560px wide. But when I ran

npx gatsby build

I got the following errors in Command Line:

npx gatsby build                                                   ⏎ ✹ ✭
success open and validate gatsby-configs - 0.083s
success load plugins - 1.829s
success onPreInit - 0.009s
success delete html and css files from previous builds - 0.029s
success initialize cache - 0.008s
success copy gatsby files - 0.235s
success onPreBootstrap - 0.017s
success createSchemaCustomization - 0.007s
success source and transform nodes - 0.601s
success building schema - 0.518s
success createPages - 0.226s
success createPagesStatefully - 0.201s
success onPreExtractQueries - 0.002s
success update schema - 0.061s
success extract queries from components - 0.639s
success write out requires - 0.008s
success write out redirect data - 0.003s
success Build manifest and related icons - 0.125s
success onPostBootstrap - 0.160s

info bootstrap finished - 8.431 s

warn "export 'windowSize' was not found in '../../hooks/windowHooks'
warn "export 'windowSize' was not found in '../../hooks/windowHooks'
success Building production JavaScript and CSS bundles - 22.721s
success Rewriting compilation hashes - 0.004s
success run queries - 25.615s - 207/207 8.08/s
failed Building static HTML for pages - 3.727s

 ERROR #95312

"window" is not available during server side rendering.

See our docs page for more info on this error: https://gatsby.dev/debug-html

2 |
3 | export const useMediaQuery = (query) => {
> 4 | const mediaMatch = window.matchMedia(query);
|             ^
5 |   const [matches, setMatches] = useState(mediaMatch.matches);
6 |     useEffect(() => {
7 |         const handler = e => setMatches(e.matches);

WebpackError: ReferenceError: window is not defined

- mediaQueryHooks.js:4 useMediaQuery
src/hooks/mediaQueryHooks.js:4:24

- Footer.js:160 Footer

src/components/Footer/Footer.js:160:42

I tried all sorts of solutions which I came across on the GatsbyJS repo and elsewhere which I won’t even get into here, because they were useless and just created even more errors.

Then I googled again for the window object as not being defined in Gatsby using React hooks. I don’t remember the exact words I used this time, but this was the only time I ended up with the right search result. This is what I came up with:

  • Use document and window with Gatsby

Jensen Bernard writes about the npm package he created called browser-monads in response to this error he also received in GatbsyJS.

All I had to do was import it into mediaQueryHooks.js where my useMediaQuery React hook resides.

// mediaQueryHooks.js
import {window} from 'browser-monads'

When I ran npx gatsby build again, it was successful! And when I deployed the changes to Netlify, the deployment to remote was successful as well!

And that was it!

I will be embedding this episode of Plugging in The Holes along with a transcript in the form of a post on interglobalmedianetwork.com for your hearing and reading pleasure. I will be including the related resource links mentioned in the podcast of course. Always do. Bye for now!

Related Resources

  • React inline styles and media queries using a custom React Hook
  • Use document and window with Gatsby
  • browser-monads on npm.js
  • Debugging HTML Builds
Tagged in: npm browser-monads window-object media-queries inline-styles jsx react gatsbyjs
Categorized under: gatsbyjs
Discuss On Twitter
  • Twitter
  • Linkedin
Maria D. Campbell

Created by Maria D. Campbell who lives and works in New York City building useful things. You should follow her on Twitter. She also has a developer blog mariadcampbell.com you may want to check out!

  • ← Newer
  • Older →
  • Business Hours
  • Monday: 9:00am - 5:00pm
  • Tuesday: 9:00am - 5:00pm
  • Wednesday: 9:00am - 5:00pm
  • Thursday: 9:00am - 5:00pm
  • Friday: 9:00am - 5:00pm
  • Saturday: Closed
  • Sunday: Closed
  • And By Appointment
  • Podast
  • Plugging In The Holes
  • Login
  • Admin Login
  • follow us on Github
  • follow us on Twitter
  • connect with us on Instagram
  • connect with us on Linkedin
ContactSitemapRSS
© 2021 Inter-Global Media Network, Inc.