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

React Router菜单跳转后远程JavaScript脚本失效,需重载页面?

解决SPA路由跳转后Google Places远程脚本失效的问题

这个问题本质是单页应用(SPA)的客户端路由特性导致的:首次加载localhost:3000时,浏览器会完整加载index.html里的所有远程脚本(包括Google Places),并执行页面初始化逻辑;但点击菜单跳转是客户端导航,不会刷新整个页面,远程脚本不会重新执行,依赖这些脚本的组件初始化逻辑也可能没触发。

下面是针对性的解决方案,按优先级排序:

1. 动态加载Google Places脚本(最可靠)

把Google Places脚本从index.html中移除,改为在需要使用它的组件内动态加载,确保每次组件挂载时都能正确初始化:

import { useEffect, useState } from 'react';

const PlacesDependentComponent = () => {
  const [isPlacesReady, setIsPlacesReady] = useState(false);

  useEffect(() => {
    // 先检查全局是否已加载Google Places
    if (window.google?.maps?.places) {
      setIsPlacesReady(true);
      initPlacesService();
      return;
    }

    // 动态创建脚本标签加载Google Places
    const script = document.createElement('script');
    script.src = `https://maps.googleapis.com/maps/api/js?key=你的API_KEY&libraries=places`;
    script.async = true;
    script.defer = true;

    script.onload = () => {
      setIsPlacesReady(true);
      initPlacesService();
    };

    script.onerror = () => {
      console.error('Google Places脚本加载失败');
    };

    document.body.appendChild(script);

    // 组件卸载时清理脚本(可选,根据需求调整)
    return () => {
      document.body.removeChild(script);
    };
  }, []);

  // 初始化Google Places服务(比如自动补全、地点搜索)
  const initPlacesService = () => {
    const inputElement = document.getElementById('places-search-input');
    if (!inputElement) return;

    // 示例:创建地点自动补全实例
    const autocomplete = new window.google.maps.places.Autocomplete(inputElement);
    autocomplete.addListener('place_changed', () => {
      const selectedPlace = autocomplete.getPlace();
      // 处理选中的地点逻辑
    });
  };

  return (
    <div>
      <input id="places-search-input" placeholder="搜索地点..." />
      {!isPlacesReady && <p>加载地点服务中...</p>}
    </div>
  );
};

export default PlacesDependentComponent;

2. 强制路由组件重新挂载

如果你的脚本已经在index.html中静态引入,但跳转后组件没重新初始化,可以通过React Router的key属性,让路由变化时强制组件重新挂载:

在App.js的路由配置中添加:

import { Routes, Route, useLocation } from 'react-router-dom';

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

  return (
    <div className="App">
      <Header />
      {/* 用location.pathname作为key,路由变化时强制重新渲染路由组件 */}
      <Routes location={location} key={location.pathname}>
        <Route path="/" element={<HomePage />} />
        <Route path="/some-page" element={<SomePage />} />
      </Routes>
    </div>
  );
}

这样每次跳转路由,目标组件都会重新挂载,组件内的初始化逻辑(比如依赖Google Places的代码)会重新执行。

3. 检查Webpack外部依赖配置

如果你的webpack.config.js中配置了externals来处理Google全局对象,确保配置正确:

module.exports = {
  // ...其他配置
  externals: {
    google: 'window.google'
  }
};

这样你可以在组件中通过import google from 'google'访问全局对象,但前提是Google脚本已经加载完成(结合动态加载方案更稳妥)。

关键注意点

  • 不要把Google Places的初始化逻辑写在window.onload或document.ready中,这些事件只会在首次页面加载时触发,SPA跳转不会触发。
  • 确保初始化逻辑操作的DOM元素,在组件挂载后已经存在(比如用useEffect的空依赖数组,保证DOM渲染完成后再执行)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:30:49