将脚本标记添加到React / JSX
我有一个相对简单的问题,尝试将内联脚本添加到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,我不想分享。
每次渲染该组件时,是否要一次又一次地获取并执行该脚本,或者只要将该组件安装到DOM中就一次?
也许尝试这样的事情:
componentWillMount () { 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';
)
这可能是你如何安装你的例子中的packages和react-document-title
, 在npm上有一个Typekit包 。
除了上面的答案,你可以这样做:
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绑定到this
脚本注入到它。
演示可以在codesandbox.io上find
我为这个特定的情况创build了一个React组件: https : //github.com/coreyleelarson/react-typekit
只需要传入你的Typekit Kit ID作为道具,你就可以走了。
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;
Alex Mcmillan提供的答案对我来说帮助最大,但对于更复杂的脚本标记并不适用。
我稍微调整了他的答案,想出了一个带有各种function的长标签的解决scheme,这些标签另外已经设置了“src”。
(对于我的使用情况,剧本需要活在脑海里,这也反映在这里):
componentWillMount () { const script = document.createElement("script"); const scriptText = document.createTextNode("complex script with functions ie everything that would go inside the script tags"); script.appendChild(scriptText); document.head.appendChild(script); }
解决scheme取决于场景。 就像我的情况一样,我不得不在反应组件中加载一个日历embedded。
Calendly寻找一个div,并读取它的data-url
属性,并在所述div中加载一个iframe。
当你第一次加载页面时,这一切都很好:首先,div与data-url
被渲染。 然后日历脚本被添加到身体。 浏览器下载并评估它,我们都快乐地回家。
当你离开,然后回到页面时,问题就来了。 这次脚本仍然在正文中,浏览器不会重新下载和重新评估。
固定:
- 在
componentWillUnmount
查找并移除脚本元素。 然后重新安装,重复上述步骤。 - input
$.getScript
。 这是一个漂亮的jQuery助手,它需要一个脚本的URI和一个成功的callback。 一旦它加载的脚本,它评估它,并触发你的成功callback。 我所要做的就是在我的componentDidMount
$.getScript(url)
。 我的render
方法已经有日历div。 它工作顺利。