Gatsby: componentDidMount() only works after page refresh

Created on 5 Apr 2018  路  3Comments  路  Source: gatsbyjs/gatsby

Description

I build this test site https://giannisdallas.netlify.com/.
If you visit the contact page you will notice a script missing. It will appear only after reloading the page.

is it a Gatsby or React issue?
I am using componentDidMount() to load the script. Here is the page code

import React,{Component} from 'react'
import Link from 'gatsby-link'
import Img from 'gatsby-image'
import upwork from'../images/logos/upwork-logo-150px.jpg'

import './contact.scss'

let test2 = `
<script type='text/javascript'>
(function(d, s) {
    var useSSL = 'https:' == document.location.protocol;
    var js, where = d.getElementsByTagName(s)[0],
    js = d.createElement(s);
    js.src = (useSSL ? 'https:' : 'http:') +  '//www.peopleperhour.com/hire/1002307300/1213788.js?width=300&height=135&orientation=vertical&theme=light&rnd='+parseInt(Math.random()*10000, 10);\
    try { where.parentNode.insertBefore(js, where); } catch (e) { if (typeof console !== 'undefined' && console.log && e.stack) { console.log(e.stack); } }\
}(document, 'script'));
</script><div id='pph-hireme'></div>
`

//const ContactPage = ({data}) => (
class ContactPage extends Component {

    constructor(props) {
        super(props);
      }    

    loadHireMe(d, s) {
        var useSSL = 'https:' == document.location.protocol;
        var js,
          where = d.getElementsByTagName(s)[0],
          js = d.createElement(s);
        js.src =
          (useSSL ? 'https:' : 'http:') +
          '//www.peopleperhour.com/hire/1002307300/1213788.js?width=300&height=135&orientation=vertical&theme=light&rnd=' +
          parseInt(Math.random() * 10000, 10);
        try {
          where.parentNode.insertBefore(js, where);
        } catch (e) {
          if (typeof console !== 'undefined' && console.log && e.stack) {
            console.log(e.stack);
          }
        }
      }

      componentDidMount() {
        this.loadHireMe(document, 'script');
      }

      render(){
          return(
    <div>
        <div className="background-svg">
        <svg version="1.2" id="Layer_1" preserveAspectRatio="none" viewBox="0 0 1920 1080" xmlns="http://www.w3.org/2000/svg">
                <polyline className="line1" points="-0.5,0.5 960,1080.5 -0.5,1080.5 "/>
                <polygon className="line2" points="-0.5,555.5 1920.5,0.5 1920.5,1080.5 -0.5,1080.5 "/>
                <polygon className="line3" points="-0.5,823.5 1920.5,268.5 1920.5,1080.5 -0.5,1080.5 "/>
            </svg>
        </div>
        <div className="hero-image">    
            <Img sizes={this.props.data.hero.sizes} />
        </div>
        <div className="Content-inner">    
            <h1>ContactPage</h1>

            <h2>Direct Contact</h2>
            <p>For anything you need or want to ask, send me a message at <strong><a href='mailto:[email protected]'>
                giannisdallas81 @ gmail.com
            </a></strong>
            </p>
            <h2>Hire me online</h2>
            <p className="upwork">
                <a href="https://www.upwork.com/o/profiles/users/_~0168d059ac7bbd584a/">
                    <img src={upwork} /> Find me on Upwork
                </a></p>
            <div id='pph-hireme'></div>
            <p><Link className="primary-button" to="/">Back to Homepage</Link></p>
        </div>
    </div>
          )
        };
    }

export default ContactPage
export const HeroImageQuery = graphql`
  query HeroImage_contact {
    hero:imageSharp(id: {regex: "/hero/"}) {
      sizes(maxWidth: 960){
        ...GatsbyImageSharpSizes_noBase64
      }
    }
  }
`

You can view my whole code here

Thank you for the support,
Giannis

All 3 comments

componentDidMount() is firing and your script is being added to the head of the document. The issue is that the script you are referencing relies on the window load event to fire, which as you've discovered only fires on the initial page load.

To get around this you could manually fire a window load event after your loadHireMe call in componentDidMount(). For example:

var evt = document.createEvent('Event');  
evt.initEvent('load', false, false);  
window.dispatchEvent(evt);

That should work but may have unintentional side effects if something else depends on the window load event.

thank you @dannywils for the input.
Always nice to learn something new.

I modified my function to

componentDidMount() {
        this.loadHireMe(document, 'script');
        var evt = document.createEvent('Event');  
        evt.initEvent('load', false, false);  
        window.dispatchEvent(evt);
      }

and there is no difference in end result. Am I missing something?

This seems to be issue with dynamically adding this script (not gatsby specific and not even react specific) so I'm closing this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dustinhorton picture dustinhorton  路  3Comments

signalwerk picture signalwerk  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

ghost picture ghost  路  3Comments

andykais picture andykais  路  3Comments