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

React路由跳转后动态注入CDN脚本未生效,如何解决?

解决React路由跳转后动态加载CDN徽章不生效的问题

问题根源

页面刷新时,脚本与DOM元素同步加载,第三方CDN脚本会自动扫描页面DOM并完成徽章初始化;但路由跳转时,组件挂载后脚本才被注入(或之前已加载过),此时脚本不会主动重新扫描新渲染的DOM节点,导致徽章无法正常显示。另外原UseScript Hook存在重复注入脚本、卸载时移除脚本可能影响其他页面使用的问题。

解决方案

1. 优化UseScript Hook

修改Hook逻辑,避免重复加载脚本,同时支持脚本加载完成后的回调:

import { useEffect, useState } from "react";

const UseScript = (url, onLoad) => {
  const [isLoaded, setIsLoaded] = useState(false);

  useEffect(() => {
    // 检查页面中是否已存在目标脚本
    const existingScript = document.querySelector(`script[src="${url}"]`);
    
    if (existingScript) {
      // 脚本已加载,直接触发初始化回调
      if (onLoad && !isLoaded) {
        onLoad();
        setIsLoaded(true);
      }
      return;
    }

    const script = document.createElement("script");
    script.src = url;
    script.async = true;

    // 脚本加载完成后执行回调
    script.onload = () => {
      setIsLoaded(true);
      if (onLoad) onLoad();
    };

    document.body.appendChild(script);

    // 不再卸载脚本,避免影响其他页面的同脚本使用
    return () => {};
  }, [url, onLoad, isLoaded]);

  return isLoaded;
};

export default UseScript;

2. 修改组件代码,手动触发徽章初始化

在组件中利用UseScript的回调,调用第三方脚本暴露的全局初始化方法,确保路由跳转后徽章能正常渲染:

import { useEffect } from "react";
import UseScript from "./UseScript"; // 路径根据实际项目调整

export default function PubItems({
  id,
  title = "This is title",
  authors = "this is the author list",
  journaL = "this is the journal name",
  issue = "This is the issue number",
  date = "This is publication date",
  doi = "this is link",
  impact = "0.00",
  metric = "this is 000",
  plum = "",
}) {
  // 加载Dimensions脚本并触发初始化
  const isDimensionsLoaded = UseScript("https://badge.dimensions.ai/badge.js", () => {
    window.DimensionsBadges?.load();
  });

  // 加载PlumX脚本并触发初始化
  const isPlumXLoaded = UseScript("//cdn.plu.mx/widget-popup.js", () => {
    window.plumx?.load();
  });

  // 组件挂载后,再次触发初始化(确保路由跳转时DOM已渲染完成)
  useEffect(() => {
    if (isDimensionsLoaded) window.DimensionsBadges?.load();
    if (isPlumXLoaded) window.plumx?.load();
  }, [isDimensionsLoaded, isPlumXLoaded]);

  return (
    <PubItemsStyles>
      <div className="pubItems_info">
        <h3>
          <a className="pubtitle" href={doi} target="_blank">
            {title}
          </a>
        </h3>

        <p className="authors">{authors}</p>
        <p className="journal">
          <span className="jName">{journaL}</span>
          <span className="jIssue">{issue}</span>
          <span className="jIssue">{impact}</span>
        </p>
        <p className="date">{date}</p>

        <div className="metrics">
          <div>
            <a className="doi" href={doi} target="_blank">
              Read Article
            </a>
          </div>

          <span>
            <a
              href={plum}
              target="_blank"
              rel="noopener noreferrer"
              className="plumx-plum-print-popup plum-bigben-theme"
              data-size="medium"
              data-popup="bottom"
            >
              plumx
            </a>
          </span>

          <span
            className="__dimensions_badge_embed__"
            data-doi={metric}
            data-style="large_rectangle"
          ></span>
        </div>
      </div>
    </PubItemsStyles>
  );
}

核心说明

  • 避免重复加载:通过检查页面中已存在的脚本,防止路由跳转时重复注入相同脚本。
  • 手动初始化:第三方徽章脚本通常会暴露全局初始化方法(如DimensionsBadges.load()、plumx.load()),调用这些方法可强制脚本重新扫描DOM并渲染新徽章。
  • 保留脚本:移除原Hook中卸载时删除脚本的逻辑,避免其他页面使用同脚本时被意外清除。

内容的提问来源于stack exchange,提问作者MD. Hasanur Rahman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 05:36:07