Adding script tag to React/JSX

后端 未结 17 958
感动是毒
感动是毒 2020-11-22 03:52

I have a relatively straightforward issue of trying to add inline scripting to a React component. What I have so far:

\'use strict\';

import \'../../styles/         


        
相关标签:
17条回答
  • 2020-11-22 04:21

    This answer explains the why behind this behavior.

    Any approach to render the script tag doesn't work as expected:

    1. Using the script tag for external scripts
    2. Using dangerouslySetInnerHTML

    Why

    React DOM (the renderer for react on web) uses createElement calls to render JSX into DOM elements.

    createElement uses the innerHTML DOM API to finally add these to the DOM (see code in React source). innerHTML does not execute script tag added as a security consideration. And this is the reason why in turn rendering script tags in React doesn't work as expected.

    For how to use script tags in React check some other answers on this page.

    0 讨论(0)
  • 2020-11-22 04:22

    The answer Alex Mcmillan provided helped me the most but didn't quite work for a more complex script tag.

    I slightly tweaked his answer to come up with a solution for a long tag with various functions that was additionally already setting "src".

    (For my use case the script needed to live in head which is reflected here as well):

      componentWillMount () {
          const script = document.createElement("script");
    
          const scriptText = document.createTextNode("complex script with functions i.e. everything that would go inside the script tags");
    
          script.appendChild(scriptText);
          document.head.appendChild(script);
      }
    
    0 讨论(0)
  • 2020-11-22 04:24

    I created a React component for this specific case: https://github.com/coreyleelarson/react-typekit

    Just need to pass in your Typekit Kit ID as a prop and you're good to go.

    import React from 'react';
    import Typekit from 'react-typekit';
    
    const HtmlLayout = () => (
      <html>
        <body>
          <h1>My Example React Component</h1>
          <Typekit kitId="abc123" />
        </body>
      </html>
    );
    
    export default HtmlLayout;
    
    0 讨论(0)
  • 2020-11-22 04:25

    According to Alex McMillan's solution, I have the following adaptation.
    My own environment: React 16.8+, next v9+

    // add a custom component named Script
    // hooks/Script.js

    import { useEffect } from 'react'
    
    const useScript = (url, async) => {
      useEffect(() => {
        const script = document.createElement('script')
    
        script.src = url
        script.async = (typeof async === 'undefined' ? true : async )
    
        document.body.appendChild(script)
    
        return () => {
          document.body.removeChild(script)
        }
      }, [url])
    }
    
    export default function Script({ src, async=true}) {
    
      useScript(src, async)
    
      return null  // Return null is necessary for the moment.
    }
    

    // Use the custom compoennt, just import it and substitute the old lower case <script> tag with the custom camel case <Script> tag would suffice.
    // index.js

    import Script from "../hooks/Script";
    
    <Fragment>
      {/* Google Map */}
      <div ref={el => this.el = el} className="gmap"></div>
    
      {/* Old html script */}
      {/*<script type="text/javascript" src="http://maps.google.com/maps/api/js"></script>*/}
    
      {/* new custom Script component */}
      <Script src='http://maps.google.com/maps/api/js' async={false} />
    </Fragment>
    
    0 讨论(0)
  • 2020-11-22 04:26
    componentDidMount() {
      const head = document.querySelector("head");
      const script = document.createElement("script");
      script.setAttribute(
        "src",
        "https://assets.calendly.com/assets/external/widget.js"
      );
      head.appendChild(script);
    }
    
    0 讨论(0)
  • 2020-11-22 04:29

    You can also use react helmet

    import React from "react";
    import {Helmet} from "react-helmet";
    
    class Application extends React.Component {
      render () {
        return (
            <div className="application">
                <Helmet>
                    <meta charSet="utf-8" />
                    <title>My Title</title>
                    <link rel="canonical" href="http://example.com/example" />
                    <script src="/path/to/resource.js" type="text/javascript" />
                </Helmet>
                ...
            </div>
        );
      }
    };
    

    Helmet takes plain HTML tags and outputs plain HTML tags. It's dead simple, and React beginner friendly.

    0 讨论(0)
提交回复
热议问题