我有一个相对简单的问题,试图将内联脚本添加到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实际上在使用,我不想分享。


当前回答

Alex Mcmillan提供的答案对我帮助最大,但对于更复杂的脚本标记不太适用。

我稍微调整了他的答案,提出了一个解决方案的长标签与各种功能,另外已经设置“src”。

(对于我的用例,脚本需要生活在头部,这是反映在这里):

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

其他回答

你可以试着使用下面的语句:

确保你相信剧本

 <script>{`
            function myFunction(index, row) {
                return index;
            }
        `}
</script>

除了上面的答案,你还可以这样做:

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

div被绑定到此,脚本被注入其中。

演示可以在codesandbox.io上找到

老实说,对于React来说,不要在头文件中添加<script>标签。这是一个痛苦的屁股得到一个回调时,他们已经完全加载。相反,使用像@charlietango/useScript这样的包在需要时加载脚本,并在脚本完成时获得状态更新。

使用示例:

import React from 'react'
import useScript, { ScriptStatus } from '@charlietango/use-script'
 
const Component = () => {
  const [ready, status] = useScript('https://api.google.com/api.js')
 
  if (status === ScriptStatus.ERROR) {
    return <div>Failed to load Google API</div>
  }
 
  return <div>Google API Ready: {ready}</div>
}
 
export default Component

PS.如果你使用redux来告诉其他组件你的脚本何时加载,并且像我一样使用redux-persist,不要忘记在你的redux-persist设置中包含一个修饰符,它总是在redux备份中将脚本加载的redux值设置为false。

你可以使用npm postscribe在react组件中加载脚本

postscribe('#mydiv', '<script src="https://use.typekit.net/foobar.js"></script>')

对于多个脚本,使用这个

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