82

I would like to add to my react component a

<script>http://xxx.xxx/XX.js</script>

I know I can simply add it using JSX , what I don't know is how to use it,

for instance this script has a function called A.Sort() , how can I call it and use it from a component?

peterh
  • 11,875
  • 18
  • 85
  • 108
metalice
  • 941
  • 1
  • 8
  • 10

9 Answers9

97

You can load the script asynchronously and access it on load.

componentDidMount() {
  const script = document.createElement("script");
  script.src = "/static/libs/your_script.js";
  script.async = true;
  script.onload = () => this.scriptLoaded();

  document.body.appendChild(script);
}

It should get attached to the window.

 scriptLoaded() {
   window.A.sort();
 }

or

scriptLoaded() {
  A.sort();
}
Florian
  • 1,182
  • 8
  • 10
  • 1
    I am not sure this is the best way to load an external script in ReactJS? Have you tested performance of adding script to index.html with a CDN or doing what you did inside a component? – Alex Feb 25 '20 at 13:25
  • 2
    What does `window.A` reference to? Every time I call it within my `loaded` function, I get a runtime error `Cannot read property 'sort' of undefined` – GROVER. Dec 30 '20 at 06:18
  • @GROVER. A is a loaded module that attaches itself to the window object. A is only used for illustration purpose. – Florian Jan 21 '21 at 13:01
  • @Flow for me script loaded method being called, but the method inside the js file I am not able to call, and it's not available in window also – u_pendra Aug 13 '21 at 08:31
26

You can include the tag in the /public/index.html, and then use the script as you use it in normal JS code, following example for if you want to use jQuery:

in your public/index.html include the following:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

And then anywhere you can use the jQuery functionality as usual:

window.$("#btn1").click(function(){
  alert("Text: " + $("#test").text());
});
Bilal
  • 582
  • 4
  • 8
  • 5
    Why a reference to jQuery? – keul Nov 20 '18 at 15:43
  • 4
    I referenced jQuery as an example of referencing an external JS to show how to include and use a JS file – Bilal Nov 20 '18 at 15:44
  • Ah! I see, sorry, I didn't get you context. – keul Nov 20 '18 at 15:46
  • 1
    this is not good for me, because i want dynamically add it and not hard code it.. so i must use it inside a component... – metalice Nov 20 '18 at 15:46
  • 1
    If your external script needs to be included in the header, you can use React Helmet to manage what goes into the header of the index.html page dynamically https://github.com/nfl/react-helmet – Bilal Nov 20 '18 at 15:53
  • The best answer for external scripts where you pull it all in and not just what you need is to use a CDN – Alex Feb 25 '20 at 13:43
  • using jquery is not a standard for React.JS – Matheus Ribeiro Dec 22 '21 at 13:59
13

You can use React Helmet npm

step 1 : npm i react-helmet

step 2 :

<Helmet>
    <script src="/path/to/resource.js" type="text/javascript" />
</Helmet>
Rahul Sarma
  • 763
  • 2
  • 8
  • 17
9

Sometimes we need to work with external js libraries in such cases we need to insert script tags into components, but in react we use jsx, so we can’t add script tags directly just like how we add in HTML.

In this example, we will see how to load an external script file into a head, body elements, or component.

componentDidMount() {
    const script = document.createElement("script");
    script.async = true;
    script.src = "https://some-scripturl.js";
    script.onload = () => this.scriptLoaded();



    //For head
    document.head.appendChild(script);

    // For body
    document.body.appendChild(script);

    // For component
    this.div.appendChild(script);

  }
Hany Moh.
  • 949
  • 1
  • 11
  • 11
5

You can either modify your index.html file (if you are using one) by adding the required script.

Alternatively, if you can't edit it or you are not using it, there's a bunch of add-ons that solve this, for example react-load-script

keul
  • 7,673
  • 20
  • 45
  • 4
    ok, react-load-script seems to be something that might work, but after i load it, how can i use the functions inside the script if im loading it using react-load-script? as mention , for example using the function A.sort() that is in the script... – metalice Nov 20 '18 at 15:49
2

After adding this script into your index.html

<script>http://xxx.xxx/XX.js</script>

you might check the available functions if you console.log(window) in App.js (or, wherever you want). Once you check the exact function, then you can use it like

window.A.sort();

I think this could be the simplest way. Just remember that you have to write 'window.' on the left side of your function.

Jason KIM
  • 117
  • 7
0

If you want to import script in multiple components, then you can create your own custom hook that allows you to insert script in desired component:

import { useEffect } from 'react'
const importScript = src => {
  useEffect(() => {
    const script = document.createElement('script')
    script.src = src
    script.async = true
    document.body.appendChild(script)
    return () => {
      document.body.removeChild(script)
    }
  }, [src])
}
export default importScript

Using it on your desired component:

import importScript from 'import-path'
const DesiredComponent = props => {
  importScript("/path/to/resource")
  // ... rest of the code
}
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
0

If the script you're importing is a JS module, i.e., it has variables and/or functions exported using the export declaration, then, in your component, you can use the await operator along with the import declaration (MDN) like so:

const importedModule = await import("http://xxx.xxx/XX.js")

(Remember to call the above declaration inside an async function)

And then you can use it like so:

importedModule.sort()

If you see an error that says something like Error: Cannot find module in the console, change your declaration to be like so:

const importedModule = await import(/* webpackIgnore: true */ "http://xxx.xxx/XX.js")

(On why the /* webpackIgnore: true */ comment is required, read this very-well-written answer)

If you import the external module like this, you won't need to add the <script> tag in your html.

Nikhil Sinha
  • 481
  • 7
  • 5
-2

A hooks version.

import * as React from "react";

function loadError(onError) {
  console.error(`Failed ${onError.target.src} didn't load correctly`);
}

function External() {
  React.useEffect(() => {
    const LoadExternalScript = () => {
      const externalScript = document.createElement("script");
      externalScript.onerror = loadError;
      externalScript.id = "external";
      externalScript.async = true;
      externalScript.type = "text/javascript";
      externalScript.setAttribute("crossorigin", "anonymous");
      document.body.appendChild(externalScript);
      externalScript.src = `https://externalurl.example.com/external.js?key=9393ABCDEFGH`;
    };
    LoadExternalScript();
  }, []);

  return <></>;
}

export default External;
Hillsie
  • 607
  • 1
  • 6
  • 15