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

Next.js中如何在状态变化时重新执行动态src的Script?

解决Next.js 13.2.3中Script组件随状态变化重新加载的问题

首先明确:beforeInteractive策略的脚本属于页面预加载资源,只会在页面初始化阶段执行一次,无法随状态变化重新加载。要实现动态切换脚本的需求,得换用运行时策略并配合手动管理逻辑,以下是两种可行方案:

方案1:用key属性触发Script组件重渲染

给Script组件绑定与动态URL关联的key值,当URL变化时,key改变会触发Next.js卸载旧脚本、加载新脚本。注意要把策略换成lazyOnload或afterInteractive这类运行时加载策略:

import { Script } from 'next/script';

function DynamicScript({ urlThatCanChange }) {
  return (
    <Script
      src={`${urlThatCanChange}/library.js`}
      strategy="lazyOnload"
      key={urlThatCanChange}
    />
  );
}

方案2:手动操作DOM控制脚本生命周期

如果需要更精细的副作用控制(比如清理旧脚本的全局变量、事件监听),可以直接通过DOM API创建和移除脚本:

'use client';
import { useEffect } from 'react';

function DynamicScript({ urlThatCanChange }) {
  useEffect(() => {
    // 移除已存在的同地址旧脚本
    const oldScript = document.querySelector(`script[src="${urlThatCanChange}/library.js"]`);
    if (oldScript) {
      oldScript.remove();
      // 按需清理脚本副作用,比如:window.libraryInstance = null;
    }

    // 创建新脚本元素
    const newScript = document.createElement('script');
    newScript.src = `${urlThatCanChange}/library.js`;
    newScript.async = true;

    // 可选:监听脚本加载完成事件,执行初始化逻辑
    newScript.onload = () => {
      console.log('新脚本加载完成,可执行初始化');
    };

    document.body.appendChild(newScript);

    // 组件卸载或URL变化时清理脚本
    return () => {
      newScript.remove();
      // 再次清理副作用
    };
  }, [urlThatCanChange]);

  return null;
}

关键注意点

  • 必须放弃beforeInteractive策略:该策略的脚本在预渲染阶段就已注入,不支持动态更新。
  • 清理副作用:切换脚本时一定要清理旧脚本留下的全局变量、事件监听等,避免内存泄漏或逻辑冲突。
  • 客户端组件限制:Next.js 13中,这类动态DOM操作逻辑必须放在标记了'use client'的客户端组件中。

内容的提问来源于stack exchange,提问作者5tormTrooper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:37:06