在 React 中停止路由更改时的音频?

Tob*_*e O 0 javascript frontend reactjs react-router

每个人。我仍然习惯于 React 和 React Router,这是我不知道的一件事。

所以,我有一个同时播放视频(静音)和音轨的应用程序。我正在使用React Player来播放两者。我的观点是这样的(VideoPlayer 是 react-player 标签):

<div>
    <VideoPlayer url={this.props.audio} playing={this.state.playing} />
    <VideoPlayer url={this.props.video} playing={this.state.playing} />
</div>
Run Code Online (Sandbox Code Playgroud)

这个设置对我有用,我能够通过一个共同的状态来播放和控制它们。我可以通过连接到按钮的事件处理程序阻止它们:

handleStop() {
    this.setState({playing: false})
}
Run Code Online (Sandbox Code Playgroud)

这也有效。

然而,问题是,一旦我导航到不同的路线,音频(可能还有视频)仍然在后台播放。实际上,让我换个说法,当我更改路线时,音频会在后台重新启动

从 react-router docs阅读此页面后,我尝试包含调用handleStop各种生命周期事件的逻辑,但没有一个能成功。到目前为止,我试图把调用handleStopcomponentWillReceivePropscomponentWillUpdatecomponentDidUpdatecomponentWillUnmount

我得到的最接近的是将调用放入componentWillUnmount,但我总是收到关于设置未安装组件状态的错误(这也没有意义,如果卸载之前调用?)。

那么,有没有人知道在哪里打电话给handleStop?

提前致谢。

小智 5

我知道这个问题已经超过 4 年了,但我今天遇到了这个问题,想分享我的解决方法......

import React, { useRef, useEffect } from 'react';
import waves from '../audio/waves.mp3';
    
const RockyCoast = (props) => {
    // the audio variable needs to be stored in a ref in order to access it across renders
    let audio = useRef();
    // start the audio (using the .current property of the ref we just created) when the component mounts using the useEffect hook
    useEffect(() => {
        audio.current = new Audio(waves)
        audio.current.play()
    }, [])
    // Stop the audio when the component unmounts
    // (not exactly what you asked re React Router, but similar idea)
    useEffect(() => {
        return () => {
            audio.current.pause()
            console.log("in cleanup")
        }
    }, [])
    ...

    return (
        <>
            ...
        </>
    )
}
export default RockyCoast;

Run Code Online (Sandbox Code Playgroud)

这正常工作的一些关键原因是因为我们将audio变量声明为 React ref,以便我们可以再次访问它以在卸载时暂停它。两个useEffect调用的依赖数组相同也很重要(在我的例子中它们是空的,以便它们表现得像componentDidMountcomponentWillUnmount)。

问题是专门询问有关使用 React Router 更改路由的问题,因此您的特定情况可能需要做更多的工作,但是如果像我一样,您为需要此功能的路由渲染了一个父组件,如下所示:

<Route exact path="/habitat/rocky_coast">
    <RockyCoast />
</Route>
Run Code Online (Sandbox Code Playgroud)

(音频在页面上播放,然后在我们导航到不同的页面时停止),这个解决方案非常有效。

希望这可以帮助其他一些像我一样的可怜的开发人员设法创建一个项目,其中包含大量的音频剪辑,哈哈!