You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js <Link>导航后脚本不重新执行的解决方案求助

Next.js 单页导航下重新执行脚本的解决方案

在Next.js中使用<Link>标签进行SPA导航时,页面切换不会触发全局脚本重新执行,仅首次加载或刷新页面时脚本才会运行;而普通<a>标签会重载页面,脚本能正常执行。以下是保留SPA特性同时实现脚本重新执行的几种方法:


两种导航方式对比

SPA导航(不刷新页面)

<Link href="/page1">
  <a>Page 1</a>
</Link>
<Link href="/page2">
  <a>Page 2</a>
</Link>

普通导航(刷新页面)

<a href="/page1">Page 1</a>
<a href="/page2">Page 2</a>

当前脚本加载组件

通过MyScripts组件加载脚本,其中onReady回调会在每次页面切换时触发:

export default const MyScripts = () => {
    return (
        <Script
            strategy="afterInteractive"
            type="module"
            src="/scripts/myScript.js"
            onReady={() => {
                console.log("Ready")
            }}
        /> 
    )
}

解决方案

方案1:封装脚本核心逻辑,通过onReady调用

将脚本中的核心功能封装为可调用函数,在onReady中手动触发执行:

  1. 修改myScript.js,抽出核心逻辑:
// /scripts/myScript.js
export const initMyScript = () => {
  // 原脚本的核心逻辑,比如初始化事件、渲染内容等
  console.log("脚本核心逻辑执行");
};

// 首次加载自动执行
initMyScript();
  1. 在MyScripts组件中导入并调用该函数:
import { initMyScript } from "/scripts/myScript.js";

export default const MyScripts = () => {
    return (
        <Script
            strategy="afterInteractive"
            type="module"
            src="/scripts/myScript.js"
            onReady={() => {
                initMyScript(); // 每次页面切换时重新执行核心逻辑
            }}
        /> 
    )
}

方案2:监听路由切换事件重新加载脚本

利用Next.js的useRouter钩子监听routeChangeComplete事件,在路由切换完成后重新加载脚本:

import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default const MyScripts = () => {
  const router = useRouter();

  useEffect(() => {
    const reloadScript = () => {
      // 移除旧脚本,避免重复执行
      const oldScript = document.querySelector('script[src="/scripts/myScript.js"]');
      if (oldScript) oldScript.remove();
      // 创建并加载新脚本
      const newScript = document.createElement('script');
      newScript.type = 'module';
      newScript.src = '/scripts/myScript.js';
      document.body.appendChild(newScript);
    };

    // 首次加载执行一次
    reloadScript();
    // 监听路由切换事件
    router.events.on('routeChangeComplete', reloadScript);
    
    // 组件卸载时移除监听
    return () => {
      router.events.off('routeChangeComplete', reloadScript);
    };
  }, [router]);

  return null;
}

方案3:清理副作用后重新执行脚本

如果无法修改原脚本,可先清理脚本产生的副作用(比如绑定的事件、生成的DOM元素),再重新加载脚本:

import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default const MyScripts = () => {
  const router = useRouter();

  const loadAndInitScript = () => {
    // 清理旧副作用:示例为克隆元素移除绑定事件
    document.querySelectorAll('.script-target').forEach(el => {
      const clone = el.cloneNode(true);
      el.replaceWith(clone);
    });

    // 重新加载脚本
    const script = document.createElement('script');
    script.type = 'module';
    script.src = '/scripts/myScript.js';
    const oldScript = document.querySelector('script[src="/scripts/myScript.js"]');
    if (oldScript) oldScript.remove();
    document.body.appendChild(script);
  };

  useEffect(() => {
    loadAndInitScript();
    router.events.on('routeChangeComplete', loadAndInitScript);
    return () => router.events.off('routeChangeComplete', loadAndInitScript);
  }, [router]);

  return null;
}

内容的提问来源于stack exchange,提问作者Dan P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:55:26