Muchao
Muchao

Reputation: 3

How to add js to React components in Gatsby?

I'm trying to add the scroll function in script tags to this header component in Gatsby. I know it could work in html and not in react, but what is the right way to do it? Thanks!

import React from 'react'
import Link from 'gatsby-link'
import './header.css'

const Header = () => (
  <div className='Header'>

    <div className='HeaderGroup'>
      <Link to='/'><img src={require('../img/logo_nav.png')} width='60' /></Link>
      <Link to='/index'>Selected Works</Link>
      <Link to='/uber'>Uber Thoughts</Link>
      <Link to='/awards'>Awards</Link>
      <Link to='/about'>About</Link>
    </div>
  </div>
)

export default Header

<script>
  $(window).scroll(function () {
    if ($(window).scrollTop() > 10) {
      $('.Header').addClass('floatingHeader');
    } else {
      $('.Header').removeClass('floatingHeader');
    }
  }
</script>

Upvotes: 0

Views: 5100

Answers (1)

bntzio
bntzio

Reputation: 1324

If you want scripts to load before the DOM is ready you can add your scripts inside html.js file.

From the Gatsby docs:

Gatsby uses a React component to server render the and other parts of the HTML outside of the core Gatsby application.

Read more about it here.

In your case, what you can do is to write your script inside the componentDidMount react lifecycle method, because you need access to the DOM (as you're using jQuery there) you need to run the script after the body has been loaded, so placing your script in the <head> won't work, you need to add it inside the componentDidMount method by first making your component a class component to get access to the react lifecycle methods.

import React from 'react'
import Link from 'gatsby-link'
import $ from 'jquery'

import './header.css'

class Header extends React.Component {
  componentDidMount () {
    $(window).scroll(function () {
      if ($(window).scrollTop() > 10) {
        $('.Header').addClass('floatingHeader');
      } else {
        $('.Header').removeClass('floatingHeader');
      }
    })
  }
  render () {
    return (
      <div className='Header'>
        <div className='HeaderGroup'>
          <Link to='/'><img src={require('../img/logo_nav.png')} width='60' /></Link>
          <Link to='/index'>Selected Works</Link>
          <Link to='/uber'>Uber Thoughts</Link>
          <Link to='/awards'>Awards</Link>
         <Link to='/about'>About</Link>
        </div>
      </div>
    )
  }
}

export default Header

You can also use a Gatsby layout template like the gatsby-starter-blog project and put your script at the bottom of the {children} call as a <script>Your script</script> and it will be available in all your pages, same as using the html.js file but since you need access to the DOM you need to put it inside the body for your script to work (more info about Gatsby layouts here).

Upvotes: 1

Related Questions