<script> - This feature is available in the latest Canary

Canary

React 对 <script> 的扩展当前仅在 React Canary 与 experimental 渠道中可用。在 React 的稳定版本中,<script> 仅作为 浏览器内置 HTML 组件 使用。请在 此处了解更多关于 React 发布渠道的信息

浏览器内置的 <script> 组件 允许向文档添加脚本。

<script> alert("hi!") </script>

参考

<script>

渲染 浏览器内置的 <script> 组件 以向文档添加内联或外部脚本。可以在任何组件中渲染 <script>,React 将在某些情况下将相应的 DOM 元素放置在文档头部,并对相同的脚本进行去重。

<script> alert("hi!") </script>
<script src="script.js" />

参见下方更多示例

属性

<script> 支持所有 通用元素属性

它应该要么具有 children 属性,要么具有 src 属性。

  • children:字符串,内联脚本的源代码。
  • src:字符串,外部脚本的 URL。

但也支持其他属性:

  • async:布尔值,允许浏览器延迟执行脚本,直到文档的其余部分已经处理完毕——这是性能优化的首选行为。
  • crossOrigin:字符串,表示要使用的 CORS 策略,其可能的值为 anonymoususe-credentials
  • fetchPriority:字符串,用于指示浏览器在同时获取多个脚本时按优先级对脚本进行排名,可能的值包括 "high""low""auto"(默认值)。
  • integrity:字符串,脚本的密码哈希,用于 验证其真实性
  • noModule:布尔值,表示在支持 ES 模块的浏览器中禁用脚本——用于为不支持的浏览器提供一个后备脚本。
  • nonce:字符串,表示使用严格内容安全策略时允许资源的 加密随机数
  • referrer:字符串,指定在获取脚本以及脚本依次获取任何资源时发送的 referer 请求头
  • type:字符串,指定脚本是一个 传统脚本、ES 模块还是导入映射

禁用 React 对脚本的 特殊处理 的属性:

  • onError:脚本加载失败时调用的函数。
  • onLoad:脚本加载完成时调用的函数。

不建议与 React 一起使用的属性:

  • blocking:字符串。如果其设置为 "render",指示浏览器在脚本加载完成之前不要渲染页面。React 使用 Suspense 提供了更精细的控制。
  • defer:字符串,用于防止浏览器在文档加载完成之前执行脚本。与流式服务器端渲染组件不兼容。请改用 async 属性。

特殊的渲染行为

React 可以将 <script> 组件移动到文档的 <head> 中,并对相同脚本进行去重,并在脚本加载时 挂起

可以提供 srcasync={true} 属性以选择行为。如果脚本具有相同的 src,React 将对脚本去重。async 属性必须为 true 才能安全地移动脚本。

如果提供了 onLoadonError 之类的任何属性,则没有特殊行为,因为这些属性表明正在组件内手动管理脚本的加载。

这种特殊处理带来两个注意事项:

  • 在脚本被渲染后,React 将忽略属性的更改(React 在开发环境中会对这种情况发出警告)。
  • 即使渲染它的组件已被卸载,React 也可能将脚本保留在 DOM 中(这不会产生影响,因为脚本只在插入到 DOM 中时执行一次)。

用法

渲染内部脚本

如果一个组件依赖于某些脚本才能正确显示,则可以在组件内部渲染 <script>

如果提供了 srcasync 属性,组件会在脚本加载时挂起。React 会对具有相同 src 的脚本去重,因此即使多个组件渲染了相同的脚本,也只会将其中一个插入到 DOM 中。

import ShowRenderedHTML from './ShowRenderedHTML.js';

function Map({lat, long}) {
  return (
    <>
      <script async src="map-api.js" />
      <div id="map" data-lat={lat} data-long={long} />
    </>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <Map />
    </ShowRenderedHTML>
  );
}

注意

想要使用脚本时,调用 preinit 函数可能会有益处。调用此函数可能会使浏览器比仅渲染 <script> 组件更早地开始获取脚本,例如通过发送 HTTP 103 Early Hints 响应

渲染内联脚本

如果需要包含内联脚本,请将 <script> 组件渲染为其子元素的脚本源代码。内联脚本不会被去重或移动到文档 <head> 中,由于它们不加载任何外部资源,因此不会导致组件挂起。

import ShowRenderedHTML from './ShowRenderedHTML.js';

function Tracking() {
  return (
    <script>
      ga('send', 'pageview');
    </script>
  );
}

export default function Page() {
  return (
    <ShowRenderedHTML>
      <h1>My Website</h1>
      <Tracking />
      <p>Welcome</p>
    </ShowRenderedHTML>
  );
}