it-swarm.com.de

Skript-Tag zu React / JSX hinzufügen

Ich habe ein relativ einfaches Problem, wenn ich versuche, Inline-Skripte zu einer React -Komponente hinzuzufügen. Was ich bisher habe:

'use strict';

import '../../styles/pages/people.scss';

import React, { Component } from 'react';
import DocumentTitle from 'react-document-title';

import { prefix } from '../../core/util';

export default class extends Component {
    render() {
        return (
            <DocumentTitle title="People">
                <article className={[prefix('people'), prefix('people', 'index')].join(' ')}>
                    <h1 className="tk-brandon-grotesque">People</h1>

                    <script src="https://use.typekit.net/foobar.js"></script>
                    <script dangerouslySetInnerHTML={{__html: 'try{Typekit.load({ async: true });}catch(e){}'}}></script>
                </article>
            </DocumentTitle>
        );
    }
};

Ich habe auch versucht:

<script src="https://use.typekit.net/foobar.js"></script>
<script>try{Typekit.load({ async: true });}catch(e){}</script>

Keiner der beiden Ansätze scheint das gewünschte Skript auszuführen. Ich vermute, es ist eine einfache Sache, die ich vermisse. Kann jemand helfen?

PS: Ignoriere die Fußleiste, ich habe einen echten Ausweis, den ich nicht teilen möchte.

180
ArrayKnight

Möchten Sie das Skript immer wieder abrufen und ausführen, jedes Mal, wenn diese Komponente gerendert wird, oder nur einmal, wenn diese Komponente in das DOM eingebunden wird?

Vielleicht versuchen Sie etwas wie folgt:

componentDidMount () {
    const script = document.createElement("script");

    script.src = "https://use.typekit.net/foobar.js";
    script.async = true;

    document.body.appendChild(script);
}

Dies ist jedoch nur dann sehr hilfreich, wenn das zu ladende Skript nicht als Modul/Paket verfügbar ist. Erstens würde ich immer:

  • Suchen Sie nach dem Paket auf npm
  • Laden Sie das Paket herunter und installieren Sie es in meinem Projekt (npm install typekit)
  • import das Paket, wo ich es brauche (import Typekit from 'typekit';)

Dies ist wahrscheinlich, wie Sie die Pakete react und react-document-title aus Ihrem Beispiel installiert haben, und es gibt ein Typekit-Paket verfügbar unter npm .

254
Alex McMillan

Zusätzlich zu den obigen Antworten können Sie dies tun:

import React from 'react';

export default class Test extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount() {
    const s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.innerHTML = "document.write('This is output by document.write()!')";
    this.instance.appendChild(s);
  }

  render() {
    return <div ref={el => (this.instance = el)} />;
  }
}

Das div ist an this gebunden und das Skript wird in das div eingefügt.

Demo finden Sie unter codesandbox.io

42
sidonaldson

Am liebsten benutze ich den React -Helm - eine Komponente, mit der Sie den Dokumentenkopf auf eine Art und Weise bearbeiten können, wie Sie es wahrscheinlich bereits gewohnt sind.

z.B.

import React from "react";
import {Helmet} from "react-helmet";

class Application extends React.Component {
  render () {
    return (
        <div className="application">
            <Helmet>
                <script src="https://use.typekit.net/foobar.js"></script>
                <script>try{Typekit.load({ async: true });}catch(e){}</script>
            </Helmet>
            ...
        </div>
    );
  }
};

https://github.com/nfl/react-helmet

32
Patrice Wrex

Die Antwort Alex Mcmillan hat mir am meisten geholfen, hat aber bei einem komplexeren Skript-Tag nicht ganz funktioniert.

Ich habe seine Antwort leicht überarbeitet, um eine Lösung für ein langes Tag mit verschiedenen Funktionen zu finden, das zusätzlich bereits "src" gesetzt hat.

(Für meinen Anwendungsfall musste das Skript im Kopf leben, was sich auch hier widerspiegelt):

  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);
  }
11
jake2620

Wenn Sie _<script>_ in SSR (serverseitiges Rendern) blockieren müssen, funktioniert ein Ansatz mit componentDidMount nicht.

Sie können stattdessen die Bibliothek react-safe verwenden. Der Code in React lautet:

_import Safe from "react-safe"

// in render 
<Safe.script src="https://use.typekit.net/foobar.js"></Safe.script>
<Safe.script>{
  `try{Typekit.load({ async: true });}catch(e){}`
}
</Safe.script>
_
9
scabbiaza

Ich habe eine React -Komponente für diesen speziellen Fall erstellt: https://github.com/coreyleelarson/react-typekit

Sie müssen lediglich Ihre Typekit Kit-ID als Requisite übergeben und können loslegen.

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;
7
Corey Larson

Es gibt eine sehr nette Problemumgehung mit Range.createContextualFragment.

/**
 * Like React's dangerouslySetInnerHTML, but also with JS evaluation.
 * Usage:
 *   <div ref={setDangerousHtml.bind(null, html)}/>
 */
function setDangerousHtml(html, el) {
    if(el === null) return;
    const range = document.createRange();
    range.selectNodeContents(el);
    range.deleteContents();
    el.appendChild(range.createContextualFragment(html));
}

Dies funktioniert für beliebiges HTML und behält auch Kontextinformationen wie document.currentScript bei.

3
Maximilian Hils

Sie können npm postscribe verwenden, um das Skript in die Reaktionskomponente zu laden

_postscribe('#mydiv', '<script src="https://use.typekit.net/foobar.js"></script>')
_
2
Ashh
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
Marlcg58

verwenden Sie dies für mehrere Skripte

var loadScript = function(src) {
  var tag = document.createElement('script');
  tag.async = false;
  tag.src = src;
  document.getElementsByTagName('body').appendChild(tag);
}
loadScript('//cdnjs.com/some/library.js')
loadScript('//cdnjs.com/some/other/library.js')
0
ben

Versuchte alle vorgeschlagenen Lösungen, aber keine funktionieren. Ich versuche, dies in eine Komponente einzubetten, aber sie wird nicht geladen. Dies ist ein Banner von bannersnack.com .

<script type="text/javascript">
var bannersnack_embed = {"hash":"bxpien9pr","width":1190,"height":300,"t":1559889975,"userId":39254375,"responsive":true,"type":"html5"};
</script>
<script type="text/javascript" src="//cdn.bannersnack.com/iframe/embed.js"></script>
0
Charm

Ich habe document "undefined" beim Aktualisieren. Also habe ich es so versucht

const MyComponent = () => {
   let script = React.createElement("script", {
    src: "https://.....js path",
    async: true,
    defer: true,
    crossorigin: "anonymous"
})

return (

        <div>
            {script}
        </div>)
}
0
Asanka