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
相关产品推荐
相关产品推荐

