浏览器内置的 <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 策略,其可能的值为anonymous和use-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> 中,并对相同脚本进行去重。
可以提供 src 和 async={true} 属性以选择行为。如果脚本具有相同的 src,React 将对脚本去重。async 属性必须为 true 才能安全地移动脚本。
这种特殊处理带来两个注意事项:
- 在脚本被渲染后,React 将忽略属性的更改(React 在开发环境中会对这种情况发出警告)。
- 即使渲染它的组件已被卸载,React 也可能将脚本保留在 DOM 中(这不会产生影响,因为脚本只在插入到 DOM 中时执行一次)。
用法
渲染内部脚本
如果组件依赖某些脚本才能正确显示,你可以在该组件内部渲染一个 <script>。
然而,组件可能会在脚本尚未加载完成时就已提交到 DOM。
一旦触发 load 事件,你就可以开始依赖脚本提供的内容,例如通过 onLoad 属性进行处理。
React 会对具有相同 src 的脚本进行去重;即使多个组件都渲染了该脚本,最终也只会向 DOM 插入一个。
import ShowRenderedHTML from './ShowRenderedHTML.js'; function Map({lat, long}) { return ( <> <script async src="map-api.js" onLoad={() => console.log('script loaded')} /> <div id="map" data-lat={lat} data-long={long} /> </> ); } export default function Page() { return ( <ShowRenderedHTML> <Map /> </ShowRenderedHTML> ); }
渲染内联脚本
如果需要包含内联脚本,请将 <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> ); }