将脚本标签添加到 React/JSX更新:

2022-08-29 23:16:58

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


答案 1

编辑:事情变化很快,这已经过时了 - 请参阅更新


您是要在每次渲染此组件时一次又一次地获取并执行脚本,还是在将此组件挂载到 DOM 中时只获取并执行一次脚本?

也许可以试试这样的东西:

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

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

    document.body.appendChild(script);
}

但是,仅当要加载的脚本不作为模块/包提供时,这才真正有用。首先,我总是会:

  • npm 上查找包
  • 在我的项目中下载并安装软件包 (npm install typekit)
  • import我需要的软件包(import Typekit from 'typekit';)

这可能是您安装软件包的方式,也可以从您的示例中看出,npm 上有一个 Typekit 软件包reactreact-document-title


更新:

现在我们有了钩子,更好的方法可能是像这样使用:useEffect

useEffect(() => {
  const script = document.createElement('script');

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

  document.body.appendChild(script);

  return () => {
    document.body.removeChild(script);
  }
}, []);

这使它成为自定义钩子的绝佳候选者(例如: ):hooks/useScript.js

import { useEffect } from 'react';

const useScript = url => {
  useEffect(() => {
    const script = document.createElement('script');

    script.src = url;
    script.async = true;

    document.body.appendChild(script);

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

export default useScript;

可以这样使用:

import useScript from 'hooks/useScript';

const MyComponent = props => {
  useScript('https://use.typekit.net/foobar.js');

  // rest of your component
}

答案 2

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

例如:

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