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

ReactJS中使用<Link>时外部脚本失效问题

解决React中使用跳转后外部脚本失效的问题

这个问题我之前也碰到过,本质是React单页应用的客户端路由特性导致的:用React Router的<Link>跳转时,页面不会完全刷新,主布局的componentDidMount只在应用首次加载时触发一次。当你跳转到其他页面再返回时,主布局并没有被卸载和重新挂载,所以脚本加载逻辑不会再次执行,外部脚本(比如你这里的TripAdvisor组件)自然没法正常工作。

下面给你几个可行的解决方案:

方案1:将脚本加载逻辑移到目标组件中

把脚本的加载和清理逻辑,放到需要显示TripAdvisor内容的组件里,而不是主布局。这样每次组件挂载时都会加载脚本,卸载时清理避免重复:

类组件示例

class TripAdvisorSection extends React.Component {
  componentDidMount() {
    // 创建并加载脚本
    const tripadvisorScript = document.createElement("script");
    tripadvisorScript.src = "https://www.jscache.com/wejs?wtype=selfserveprop&amp;uniq=789&amp;locationId=10467767&amp;lang=en_NZ&amp;rating=true&amp;nreviews=0&amp;writereviewlink=true&amp;popIdx=true&amp;iswide=true&amp;border=false&amp;display_version=2";
    tripadvisorScript.async = true;
    // 挂载到指定容器(确保组件render里有这个容器)
    document.getElementById('tripadvisor-container').appendChild(tripadvisorScript);
  }

  componentWillUnmount() {
    // 清理旧脚本和生成的DOM元素
    const existingScript = document.querySelector('script[src="https://www.jscache.com/wejs?wtype=selfserveprop&amp;uniq=789&amp;locationId=10467767&amp;lang=en_NZ&amp;rating=true&amp;nreviews=0&amp;writereviewlink=true&amp;popIdx=true&amp;iswide=true&amp;border=false&amp;display_version=2"]');
    if (existingScript) existingScript.remove();
    
    // 移除TripAdvisor生成的元素
    const taElements = document.querySelectorAll('.ta-selfserve-prop');
    taElements.forEach(el => el.remove());
  }

  render() {
    return <div id="tripadvisor-container"></div>;
  }
}

函数组件(useEffect)示例

import { useEffect } from 'react';

function TripAdvisorSection() {
  useEffect(() => {
    // 创建脚本
    const tripadvisorScript = document.createElement("script");
    tripadvisorScript.src = "https://www.jscache.com/wejs?wtype=selfserveprop&amp;uniq=789&amp;locationId=10467767&amp;lang=en_NZ&amp;rating=true&amp;nreviews=0&amp;writereviewlink=true&amp;popIdx=true&amp;iswide=true&amp;border=false&amp;display_version=2";
    tripadvisorScript.async = true;
    const container = document.getElementById('tripadvisor-container');
    container.appendChild(tripadvisorScript);

    // 清理函数:组件卸载时执行
    return () => {
      const existingScript = document.querySelector('script[src="https://www.jscache.com/wejs?wtype=selfserveprop&amp;uniq=789&amp;locationId=10467767&amp;lang=en_NZ&amp;rating=true&amp;nreviews=0&amp;writereviewlink=true&amp;popIdx=true&amp;iswide=true&amp;border=false&amp;display_version=2"]');
      if (existingScript) existingScript.remove();

      // 清理TripAdvisor生成的DOM
      const taElements = container.querySelectorAll('.ta-selfserve-prop');
      taElements.forEach(el => el.remove());
    };
  }, []); // 空依赖数组确保只在挂载时执行一次

  return <div id="tripadvisor-container"></div>;
}

方案2:监听路由变化,全局重新加载脚本

如果这个脚本需要在多个页面显示,你可以在主布局里监听React Router的路由变化,每次路由切换时重新加载脚本:

import { useEffect } from 'react';
import { useLocation, Outlet } from 'react-router-dom';

function MainLayout() {
  const location = useLocation();

  useEffect(() => {
    // 先清理旧脚本和DOM
    const existingScript = document.querySelector('script[src="https://www.jscache.com/wejs?wtype=selfserveprop&amp;uniq=789&amp;locationId=10467767&amp;lang=en_NZ&amp;rating=true&amp;nreviews=0&amp;writereviewlink=true&amp;popIdx=true&amp;iswide=true&amp;border=false&amp;display_version=2"]');
    if (existingScript) existingScript.remove();
    
    const taElements = document.querySelectorAll('.ta-selfserve-prop');
    taElements.forEach(el => el.remove());

    // 加载新脚本
    const tripadvisorLeft = document.createElement("script");
    tripadvisorLeft.src = "https://www.jscache.com/wejs?wtype=selfserveprop&amp;uniq=789&amp;locationId=10467767&amp;lang=en_NZ&amp;rating=true&amp;nreviews=0&amp;writereviewlink=true&amp;popIdx=true&amp;iswide=true&amp;border=false&amp;display_version=2";
    tripadvisorLeft.async = true;
    document.body.appendChild(tripadvisorLeft);
  }, [location.pathname]); // 路由path变化时触发

  return (
    <div className="layout">
      {/* 你的导航栏等布局内容 */}
      <Outlet /> {/* 渲染当前路由对应的组件 */}
    </div>
  );
}

关键注意点

  • 一定要清理旧的脚本和生成的DOM元素,否则会出现重复加载、元素叠加的问题。
  • 外部脚本的async属性可以保留,但如果脚本依赖DOM元素存在,确保容器元素已经渲染完成再加载脚本(比如在componentDidMount或useEffect里执行,此时组件已经挂载到DOM)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:34:11