在 Next.js 中检查外部脚本加载状态的方法

힘센캥거루
2025년 1월 24일(수정됨)
2
103
在 Next.js 中检查外部脚本加载状态的方法-1

1. 问题认知

在 Nextjs 中使用 onLaod 和 useState 来确认 Script 的加载状态时,出现了问题。

例如如下示例。

"use client";

import Script from "next/script";
import { useState } from "react";

export default function Page() {
  // 通过 useState 确认脚本是否加载
  // 当脚本加载完成时,在 onLoad 中改变 scriptLoad 状态
  const [scriptLoad, setScriptLoad] = useState(false);
  return (
    <div>
      <Script
        src="https://example.com/sample.js"
        onLoad={() => setScriptLoad(true)}
      />
      {scriptLoad ? <div>加载完成!</div> : <div>加载中!</div>}
    </div>
  );
}

这样的话,组件第一次挂载并且脚本加载完成后,scriptLoad 状态会从 false 正常变为 true。

问题出在脚本已经加载过一次之后,再次挂载组件的时候

在 Next.js 中检查外部脚本加载状态的方法-2

基本上,Script 组件一旦挂载后,即使用户在 Nextjs 内部的多个路由之间来回跳转,也会保证脚本只加载一次

因此在访问过该页面之后,再次访问时脚本已处于加载完成状态,于是useState 的状态就不会再发生变化

2. 使用 onReady 代替 onLoad

无论怎么搜索都找不到解决方法,于是查看了 Script 组件相关的Nextjs 官方文档

Script 组件一共可以接收 5 个 props。

在 Next.js 中检查外部脚本加载状态的方法-3
  • src:脚本路径

  • strategy:细粒度控制加载行为。只能在服务器端使用。

  • onLoad:脚本加载完成后执行

  • onReady:脚本加载完成并且每次组件挂载时都会执行

  • onError:脚本加载失败时执行

我之前正是因为用了 onLoad,所以只有在脚本第一次加载时才会发生状态变化。

只要简单地把 onLoad 换成 onReady 就能解决。

...
export default function Page() {
...
      <Script
        src="https://example.com/sample.js"
        onReady={() => setScriptLoad(true)}
      />
...

3. 后记

就为了这一个问题,不知道我纠结了多少个小时。

本来想通过 AI 来解决疑问,但不论是 Claude 还是 ChatGPT,都在说 explore 时代的代码,只会胡说八道,真是让人头大。

那一刻特别强烈地觉得,要是身边有个能拉我一把的人就好了。

在 Next.js 中检查外部脚本加载状态的方法-4

관련 글

Next.js 全栈博客开发记
Next.js 全栈博客开发记
在第一次接触网页开发大约 1 年之后,我开始想着想要拥有一个属于自己的博客。于是我就大概花了 6 个月几乎只埋头做这件事。前端部分的功能,参考金度亨先生的博客就已经足够了。我用 mdx 搭建起一个博客,其实连一周都没花到。事实上,仅靠前端也并不会给博客运营带来什么大问题。有一阵子我也觉得,只要写 m...
使用 Caddy 实现 Next.js 无停机部署(本地服务器)
使用 Caddy 实现 Next.js 无停机部署(本地服务器)
每次一有想在主页上加点什么的念头就去 build,结果中间好像偶尔会有人访问。于是 Search Console 上的分数开始一点点往下掉。觉得这样不行,就开始思考要怎么做无停机部署。1. 两个项目文件夹 + 两个终端答案出乎意料地简单:开两个终端。在一个终端里 build,另一个终端里让服务器跑着...
谷歌搜索索引自动化 - Web Search Indexing API
谷歌搜索索引自动化 - Web Search Indexing API
继上次搞完 IndexNow 之后,也决定在谷歌这边做一下自动化。查了一下,发现谷歌是通过一个叫 Web Search Indexing 的 API 来支持这个功能的。1. 适用范围官方文档中,这个 API 正式支持的范围是招聘公告和流媒体视频服务。说是为了给对实时性要求高的内容创建索引用的,但搜了...
搜索索引生成自动化 - IndexNow
搜索索引生成自动化 - IndexNow
在向 Bing 提交站点收录时才发现,Bing 提供了一个叫做 IndexNow 的功能。核心在于,可以利用 API Key,在写完文章的瞬间就立刻发起索引请求。只要用 fetch 写出类似下面这样的请求,并把它串联到「写文章」流程里,就可以在把文章保存到 DB 的同时发送索引生成请求。POST /...
被入侵的 Nextjs、React 服务器经历
被入侵的 Nextjs、React 服务器经历
我最初接触到这次安全问题是在 12 月 5 日凌晨。据说在 React 中可以在未认证的情况下进行远程代码执行。看到这条新闻后,我虽然告诉了别人,但总觉得自己应该没事,就什么想法也没有地略过了。1. 发现被入侵的痕迹结果当我想登录更新博客代码时,在终端里发现了有命令被执行过的痕迹。/bin/sh:...
在博客中添加多语言功能(NextJS、next-intl、Vercel AI SDK)
在博客中添加多语言功能(NextJS、next-intl、Vercel AI SDK)
最近我觉得博客需要多语言功能。于是决定用 next-intl 来实现多语言服务。1.i18n首先,在做多语言服务时有一些必须遵守的原则。这被称为 internationalization,单词太长,所以把首字母 i 和尾字母 n,以及中间 18 个字母合在一起,写成 i18n。1) i18n 的原则...

댓글을 불러오는 중...