Flutter InAppWebview无法检测使用useNavigate的React应用路由变化
React Router 的 useNavigate 属于前端单页路由,仅通过JS修改浏览器URL,不会触发完整的页面加载流程,所以 flutter_inappwebview 默认的 onLoadStart、onLoadStop 这类监听页面加载的回调不会被触发——因为没有发起新的HTTP请求。
解决方案1:注入JS监听路由变化(无需修改Web应用代码)
通过 flutter_inappwebview 注入自定义JS,监听单页应用的路由变化事件,再通过JS桥接把路由信息传递给Flutter。
Flutter端代码修改:
在 onLoadStop 回调中添加JS注入和消息监听逻辑:
onLoadStop: (controller, url) async { // 注入监听路由变化的JS代码 await controller.evaluateJavascript(source: """ // 监听浏览器前进后退触发的popstate事件 window.addEventListener('popstate', function() { window.flutter_inappwebview.callHandler('routeChanged', window.location.href); }); // 重写history的pushState和replaceState方法(useNavigate会调用这两个方法但不触发popstate) const originalPushState = history.pushState; history.pushState = function() { originalPushState.apply(this, arguments); window.flutter_inappwebview.callHandler('routeChanged', window.location.href); }; const originalReplaceState = history.replaceState; history.replaceState = function() { originalReplaceState.apply(this, arguments); window.flutter_inappwebview.callHandler('routeChanged', window.location.href); }; """); // 添加JS回调处理,接收路由变化通知 controller.addJavaScriptHandler(handlerName: 'routeChanged', callback: (args) { String newRoute = args[0]; print('检测到路由变化:$newRoute'); // 这里处理你的业务逻辑,比如更新状态变量 currentWebviewUri.value = WebUri(newRoute); }); // 原有的其他业务代码... }
解决方案2:Web应用主动通知Flutter(需修改React代码)
如果有权限修改React应用代码,可以在路由变化时主动向Flutter发送消息:
React端代码:
import { useLocation, useEffect } from 'react-router-dom'; function App() { const location = useLocation(); useEffect(() => { // 路由变化时触发,向Flutter发送消息 if (window.flutter_inappwebview) { window.flutter_inappwebview.callHandler('routeChanged', window.location.href); } }, [location.pathname, location.search]); // 其他组件逻辑... }
Flutter端同样添加 addJavaScriptHandler 处理消息,逻辑和方案1一致。
原有代码失效的原因
你当前依赖的 onLoadStart、onLoadStop 仅在页面刷新、跨域名跳转、新页面加载时触发,而React单页路由的变化是前端JS修改URL,没有实际的页面加载行为,所以这些回调不会被触发。
内容的提问来源于stack exchange,提问作者Sourabh Kumar
相关产品推荐
相关产品推荐

