gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.26k stars 10.31k forks source link

Trying to load JS/jQuery files after the body is rendered #7302

Closed SiddharthaSauravGogoi closed 6 years ago

SiddharthaSauravGogoi commented 6 years ago

Summary

I have a project that has several js and jQuery files that need to be loaded after the body has rendered(in simple html + css way). Script and meta tags are included in the project with the help of React Helmet.

Basically what React Helmet does is pushes all these code inside the head of the document. In other words the js + jQuery files are loaded before the DOM(VirtualDOM) is rendered. Doesn't that effect the manipulation jQuery is supposed to do?

Is there a solution for this problem?

Relevant information

Environment (if relevant)

Windows 7 64 bit

File contents (if changed)

`gatsby-config.js`: module.exports = {
  siteMetadata: {
    title: 'Gatsby Default Starter',
  },
  plugins: ['gatsby-plugin-react-helmet'],
}

package.json:

{
  "name": "gatsby-starter-default",
  "description": "Gatsby default starter",
  "version": "1.0.0",
  "author": "Kyle Mathews <mathews.kyle@gmail.com>",
  "dependencies": {
    "gatsby": "next",
    "gatsby-plugin-react-helmet": "next",
    "jquery": "^3.3.1",
    "react": "^16.4.1",
    "react-dom": "^16.4.2",
    "react-helmet": "^5.2.0"
  },
  "keywords": [
    "gatsby"
  ],
  "license": "MIT",
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "format": "prettier --write 'src/**/*.js'",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "expose-loader": "^0.7.5",
    "prettier": "^1.13.7"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/gatsbyjs/gatsby-starter-default"
  }
}

gatsby-node.js: N/A gatsby-browser.js: N/A gatsby-ssr.js: N/A

KyleAMathews commented 6 years ago

Generally you wrap your code in onReady which handles this http://learn.jquery.com/using-jquery-core/document-ready/

Also you can put jquery in a js module and import it into your gatsby-browser.js and run your code in either https://www.gatsbyjs.org/docs/browser-apis/#onInitialClientRender if you only need to run it when the page loads or https://www.gatsbyjs.org/docs/browser-apis/#onRouteUpdate where it'll be run after every page renders.

ThangLeQuoc commented 2 years ago

Another way is to use the React useEffect (for functional component) or componentDidMount (for class component). The idea is simple, after the component is completely rendered, we will append an additional <script> tag object at its end

import React, { useEffect } from 'react'

const MyComponent = () => {
    useEffect(() => {
      const mainJsTag = document.createElement('script')
      // given the js/main.js file is put in the static folder
      mainJsTag.src = 'assets/js/main.js'
      document.body.appendChild(mainJsTag)
      console.log('Component Rendered!')
    });

  return (
    <main>
      <text>Pretty much the component's body code around here</text>
    </main>
  )
}

export default MyComponent