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

React Native页面跳转后视频仍后台播放问题求助

解决React Native视频后台播放问题的几种方案

我仔细看了你的代码,你已经尝试用withNavigationFocus来处理,但可能因为状态更新时机或者组件生命周期的问题没生效。下面是几个更可靠的解决方案:

方案1:用组件生命周期钩子精准控制播放状态

getDerivedStateFromProps是静态方法,有时候状态更新会有延迟,不如直接在componentDidUpdate里处理焦点变化,同时在组件卸载时彻底停止视频:

class Shoot extends PureComponent {
  // ... 其他代码不变 ...

  componentDidUpdate(prevProps) {
    // 当屏幕失去焦点时暂停视频
    if (prevProps.isFocused !== this.props.isFocused && !this.props.isFocused) {
      this.setState({ videoPaused: true });
    }
  }

  componentWillUnmount() {
    // 组件卸载时,清空视频源并确保停止播放
    this.setState({ video: '', videoPaused: true });
    // 清理录制进度的定时器,避免内存泄漏
    if (this.value) {
      clearInterval(this.value);
    }
  }

  // 移除原来的getDerivedStateFromProps,换成上面的生命周期方法
  // static getDerivedStateFromProps(nextProps, prevState) {
  //   return { ...prevState, videoPaused: !nextProps.navigation.isFocused() }
  // }

  // ... 其他代码不变 ...
}

方案2:给Video组件添加Ref,直接控制播放实例

通过ref获取Video组件的实例,直接调用播放/暂停方法,比依赖state更直接可靠:

class Shoot extends PureComponent {
  constructor(props) {
    super(props);
    this.videoRef = React.createRef(); // 创建视频组件的ref
    // ... 其他state不变 ...
  }

  componentDidUpdate(prevProps) {
    if (prevProps.isFocused !== this.props.isFocused) {
      if (!this.props.isFocused) {
        // 直接调用暂停方法
        this.videoRef.current?.pause();
      } else {
        // 回到屏幕时可以选择继续播放(可选)
        this.videoRef.current?.play();
      }
    }
  }

  componentWillUnmount() {
    this.videoRef.current?.stop(); // 彻底停止视频播放
    clearInterval(this.value); // 清理定时器
  }

  render() {
    return (
      // ... 其他代码 ...
      <Video
        ref={this.videoRef} // 绑定ref到视频组件
        source={{uri: this.state.video}}
        style={{ position: 'absolute', top: 0, left: 0, alignItems: 'stretch', bottom: 0, right: 0, height: '90%', }}
        resizeMode="cover"
        repeat={true}
        paused={this.state.videoPaused}
      />
      // ... 其他代码 ...
    )
  }
}

方案3:监听React Navigation的屏幕失焦事件

直接监听导航的didBlur事件,当屏幕离开时触发暂停逻辑,更贴合导航场景:

class Shoot extends PureComponent {
  componentDidMount() {
    // 添加失焦监听:离开当前屏幕时暂停视频
    this.blurListener = this.props.navigation.addListener('didBlur', () => {
      this.setState({ videoPaused: true });
      this.videoRef.current?.pause();
    });

    // 可选:添加聚焦监听,回到当前屏幕时继续播放
    this.focusListener = this.props.navigation.addListener('didFocus', () => {
      this.setState({ videoPaused: false });
      this.videoRef.current?.play();
    });
  }

  componentWillUnmount() {
    // 移除监听,避免内存泄漏
    this.blurListener();
    this.focusListener();
    this.videoRef.current?.stop();
    clearInterval(this.value);
  }

  // ... 其他代码不变 ...
}

另外要注意:你代码中录制视频时的setInterval定时器,一定要在组件卸载前清理,否则不仅会导致内存泄漏,还可能干扰后续的视频状态控制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:57:34