React Router Dom v6路由切换时外部JS文件无法加载求助
React-Router-Dom v6 路由切换后外部JS库失效问题
问题描述
我使用React-Router-Dom-6,public文件夹结构如下:
在index.html中引用了模板设计用的外部JavaScript库:
<!--=============== scripts ===============--> <script src="%PUBLIC_URL%/assets/js/jquery.min.js" type="text/babel"></script> <script src="%PUBLIC_URL%/assets/js/plugins.js" type="text/babel"></script> <script src="%PUBLIC_URL%/assets/js/scripts.js" type="text/babel"></script> <script src="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.js"></script>
这些JS文件在应用启动的首页可以正常加载运行,但路由切换到其他页面时,这些库无法工作——路由已变更,但JS文件没有重新加载,尝试多种方法仍未解决。
原因分析
React是单页应用(SPA),路由切换时不会刷新整个页面,index.html里的脚本只会在应用首次加载时执行一次。后续路由切换后,新页面的DOM元素没有触发这些脚本的初始化逻辑,导致库失效。
解决方法
1. 封装初始化函数,路由切换时重新执行
- 找到
scripts.js或相关脚本里的初始化逻辑,封装成独立函数,比如window.initPagePlugins = function() { /* 原初始化代码 */ }。 - 用React Router的
useLocation监听路由变化,每次切换时调用初始化函数:
import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; function App() { const location = useLocation(); useEffect(() => { // 执行页面插件初始化 window.initPagePlugins?.(); // 单独初始化Swiper(如果需要) if (window.Swiper) { new window.Swiper('.swiper-container', { // 你的Swiper配置项 }); } }, [location.pathname]); return ( {/* 路由组件内容 */} ); }
2. 组件内按需引入库(推荐)
放弃全局引入,改为在需要使用的组件内通过import引入,更符合React组件化思想:
// 先安装依赖(如果是npm包) // npm install jquery swiper import $ from 'jquery'; import Swiper from 'swiper'; import 'swiper/css/bundle'; function TargetPage() { useEffect(() => { // 初始化jQuery插件 $('.target-element').pluginFn(); // 初始化Swiper const swiper = new Swiper('.swiper-container', { // 配置项 }); // 组件卸载时清理实例 return () => swiper.destroy(); }, []); return ( {/* 组件DOM结构 */} ); }
3. 动态重新加载脚本(应急方案,不推荐)
如果无法修改原有脚本代码,可以在路由切换时动态创建script标签重新加载,但可能存在重复加载和性能问题:
useEffect(() => { const scriptUrls = [ `${process.env.PUBLIC_URL}/assets/js/jquery.min.js`, `${process.env.PUBLIC_URL}/assets/js/plugins.js`, `${process.env.PUBLIC_URL}/assets/js/scripts.js` ]; const loadedScripts = []; scriptUrls.forEach(url => { const script = document.createElement('script'); script.src = url; script.type = 'text/javascript'; document.body.appendChild(script); loadedScripts.push(script); }); // 组件卸载时移除脚本 return () => { loadedScripts.forEach(script => script.remove()); }; }, [location.pathname]);
内容的提问来源于stack exchange,提问作者NH Dalim
相关产品推荐
相关产品推荐

