我有一个相对简单的问题,试图将内联脚本添加到React组件。到目前为止我有:

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

我也试过:

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

这两种方法似乎都不能执行所需的脚本。我猜我错过了一件简单的事。有人能帮忙吗?

PS:忽略foobar,我有一个真正的id实际上在使用,我不想分享。


当前回答

对于多个脚本,使用这个

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

其他回答

我最喜欢的方法是使用React Helmet——这是一个组件,允许您以一种您可能已经习惯的方式轻松操作文档头。

e.g.

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

你必须为这个脚本创建一个组件,你调用这个组件作为一个标准的ES6脚本标记

'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>
                </article>
            </DocumentTitle>
        );

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

有点晚了,但我决定创建我自己的@Alex Macmillan的答案后,这是通过传递两个额外的参数;放置脚本的位置,如或和设置async为true/false,这里是:

import { useEffect } from 'react';

const useScript = (url, position, async) => {
  useEffect(() => {
    const placement = document.querySelector(position);
    const script = document.createElement('script');

    script.src = url;
    script.async = typeof async === 'undefined' ? true : async;

    placement.appendChild(script);

    return () => {
      placement.removeChild(script);
    };
  }, [url]);
};

export default useScript;

调用它的方式与本文中接受的答案完全相同,但有两个额外的参数(再次):

// First string is your URL
// Second string can be head or body
// Third parameter is true or false.
useScript("string", "string", bool);

对于多个脚本,使用这个

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

要在head tag <head>中添加脚本标签或代码,请使用react-helmet包。它很轻,有很好的文档。

在script标签中添加Js代码

    function htmlDecode(html) {
      return html.replace(/&([a-z]+);/ig, (match, entity) => {
        const entities = { amp: '&', apos: '\'', gt: '>', lt: '<', nbsp: '\xa0', quot: '"' };
        entity = entity.toLowerCase();
        if (entities.hasOwnProperty(entity)) {
          return entities[entity];
        }
        return match;
      });
    }
  render() {
    const scriptCode = `<script type="text/javascript">
          {(function() {
          window.hello={
            FIRST_NAME: 'firstName',
            LAST_NAME: 'lastName',
          };
          })()}
          </script>`
    return(
      <div dangerouslySetInnerHTML={{ __html: this.htmlDecode(scriptCode) }} />;
    );
  }

这段代码可以通过console.log(windows.hello)进行测试。