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

React Native WebView加载Wistia视频横竖屏切换后回调溢出异常

解决React Native WebView加载Wistia视频横屏关闭后的回调泄漏与UI变形问题

问题根源

横屏切换时,原生控制器触发的布局变更会让WebView内部的UIManager.measureLayout回调被反复注册,但视频关闭后这些回调未被正确清理,累积到阈值就抛出excessive number of pending callbacks: 501异常,同时残留的回调会干扰布局计算导致UI变形。

修复方案

1. 销毁WebView时清理pending回调

利用WebView的原生生命周期回调,手动清除该节点所有未处理的measureLayout回调:

import { UIManager, findNodeHandle, WebView } from 'react-native';
import { useRef } from 'react';

const webViewRef = useRef(null);

const cleanupWebViewCallbacks = () => {
  const nodeHandle = findNodeHandle(webViewRef.current);
  if (nodeHandle) {
    UIManager.removeAllMeasureCallbacks(nodeHandle);
  }
};

// 在WebView组件中绑定回调
<WebView
  ref={webViewRef}
  source={{ uri: '你的Wistia视频链接' }}
  onDestroy={cleanupWebViewCallbacks} // Android平台
  onWebViewDidClose={cleanupWebViewCallbacks} // iOS平台
/>

2. 基于屏幕方向强制WebView重建

通过useWindowDimensions监听屏幕方向变化,给WebView设置唯一key,方向切换时强制组件重建,自动清理旧实例的回调:

import { useWindowDimensions } from 'react-native';

const { width, height } = useWindowDimensions();
const isLandscape = width > height;

<WebView
  key={`wistia-webview-${isLandscape}`}
  source={{ uri: '你的Wistia视频链接' }}
  // 其他属性...
/>

3. 拦截Wistia全屏事件触发布局更新

注入JS脚本监听Wistia视频的全屏状态变化,退出全屏时主动触发WebView的resize事件,避免原生切换导致的回调堆积:

const injectedScript = `
  const wistiaPlayer = document.querySelector('.wistia_embed');
  if (wistiaPlayer) {
    wistiaPlayer.addEventListener('fullscreenchange', () => {
      if (!document.fullscreenElement) {
        window.ReactNativeWebView.postMessage('exitFullscreen');
      }
    });
  }
`;

const handleWebViewMessage = (event) => {
  if (event.nativeEvent.data === 'exitFullscreen') {
    webViewRef.current?.injectJavaScript('window.dispatchEvent(new Event("resize"));');
  }
};

<WebView
  ref={webViewRef}
  source={{ uri: '你的Wistia视频链接' }}
  injectedJavaScript={injectedScript}
  onMessage={handleWebViewMessage}
/>

4. FlatList中优化WebView复用逻辑

给FlatList的每个WebView项设置唯一key,确保组件卸载时能正确执行清理逻辑,避免复用导致的回调泄漏:

const renderVideoItem = ({ item }) => (
  <WebView
    key={item.videoId}
    source={{ uri: item.wistiaUrl }}
    onDestroy={cleanupWebViewCallbacks}
    onWebViewDidClose={cleanupWebViewCallbacks}
  />
);

<FlatList
  data={videoList}
  renderItem={renderVideoItem}
  keyExtractor={(item) => item.videoId}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:56:54