91

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?

7
  • Have you tried importing it using something like import A from 'my-js-script'; Commented Nov 20, 2018 at 15:39
  • Its external script, from the web, i cant import it as you mention.. Commented Nov 20, 2018 at 15:41
  • So the file is from a CDN? Commented Nov 20, 2018 at 15:42
  • Possible duplicate of how to import libraries from cdn in reactjs? Commented Nov 20, 2018 at 15:43
  • 3
    It is not a duplicate, the question does not have anything to do with CDN: it does not matter where the script is coming from, the question is about how to call the functions within the script. Commented Jul 22, 2019 at 11:38

10 Answers 10

104

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();
}
Sign up to request clarification or add additional context in comments.

5 Comments

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?
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. A is a loaded module that attaches itself to the window object. A is only used for illustration purpose.
@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
missing semicolon
29

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());
});

7 Comments

Why a reference to jQuery?
I referenced jQuery as an example of referencing an external JS to show how to include and use a JS file
Ah! I see, sorry, I didn't get you context.
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...
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 github.com/nfl/react-helmet
|
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>

Comments

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);

  }

Comments

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

1 Comment

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...
4

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.

Comments

2

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
}

Comments

1

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.

Comments

1

t.js

var a = 'Hello'

and inside your react component's useEffect:

useEffect(() => {
    let _script = document.createElement('script');
    _script.type = 'text/javascript';
    _script.src = "http://{ip_addr}/js/t.js";
    document.head.appendChild(aScript);
    _script.onload = function() {
    console.log(window.a)
    }
},[]);

It should print 'Hello'. This is a hack solution.Please note that variable a is declared as var.

1 Comment

This causes script to be added several times due to script being added on every mount/unmount cycle.
-1

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.