import React, { Component } from 'react'
import { Button, Input, Icon,Dropdown,Card} from 'semantic-ui-react'
import { Link } from 'react-router-dom'
import $ from 'jquery'
import styles from './Home.scss'
import Modal from './Modal.jsx'
import MakeChannelModal from './MakeChannelModal.jsx'
class Music extends React.Component {
constructor(props) {
super(props);
this.state = {
play: false,
pause: true
};
this.url = "http://streaming.tdiradio.com:8000/house.mp3";
this.audio = new Audio(this.url);
}
play(){
this.setState({
play: true,
pause: false
});
console.log(this.audio);
this.audio.play();
}
pause(){
this.setState({ play: false, pause: true });
this.audio.pause();
}
render() {
return (
<div>
<button onClick={this.play}>Play</button>
<button onClick={this.pause}>Pause</button>
</div>
);
}
}
export default Music
这是我在react应用程序中使用url(this. url)播放声音的代码。当我按下播放按钮时,它给我一个错误
未捕获的类型错误:无法读取未定义的属性"setState"
我不确定为什么会发生这种情况,因为我没有看到任何未定义的状态。;州已宣布。
我是新来的React,所以我可能错过了一些非常重要的东西。
救命啊!
7条答案
按热度按时间ghg1uchk1#
ES6类属性语法
挂钩版本(React 16.8+):
2020年3月16日更新:多个并发玩家
回应@冷课评论:
不幸的是,如果我使用多个这样的组件,当我开始播放另一个组件时,其他组件的音乐不会停止播放-有什么建议可以简单地解决这个问题吗?
不幸的是,没有一个直接的解决方案使用我们用来实现单个
Player
组件的代码库,原因是您必须以某种方式将单个玩家状态提升到MultiPlayer
父组件,以便toggle
函数能够暂停您直接交互的玩家之外的其他玩家。一种解决方案是修改钩子本身来同时管理多个音频源。下面是一个示例实现:
使用
MultiPlayer
组件的App.js
示例:其思路是管理2个并行阵列:
urls
prop 构建;urls
props是一个字符串数组(您的MP3 URL)toggle
方法根据以下逻辑更新播放器状态数组:注意,
toggle
方法被修改为接受源播放器的索引(即,单击相应按钮的子组件的索引)。实际的音频对象控制在
useEffect
中发生,就像在原始钩子中一样,但是稍微复杂一些,因为我们必须在每次更新时迭代整个音频对象数组。类似地,音频流“ended”事件的事件侦听器在第二个
useEffect
中处理,就像在原始钩子中一样,但更新为处理音频对象数组,而不是单个这样的对象。最后,从父
MultiPlayer
组件(包含多个播放器)调用新的钩子,然后使用(a)包含播放器当前状态及其源流URL的对象和(b)使用播放器索引的toggle方法Map到各个Player
。CodeSandbox demo
zlhcx6iw2#
您也可以使用
useSound
钩子来完成此操作。为此,首先安装npm软件包:
进口:
用法示例1
一个简单的方法..
用法示例2
在这个设置中,我们可以控制音量。另外,
playSound()
将在handleClick()
函数中被调用,允许你在点击时做更多的事情,而不仅仅是播放声音。有关click here或here的更多信息
alen0pnh3#
我在执行这个答案时遇到了一个不同的问题。
似乎浏览器在每次重新渲染时都在不断地尝试下载声音。
我最终使用
useMemo
作为音频,没有依赖项,这导致钩子只创建一次音频,而从不尝试重新创建它。ac1kyiln4#
我在使用Next JS时遇到了一些问题,因为音频是HTMLElement标记,最终,它给我带来了一个大错误,所以我决定进一步研究,在我的项目中的结果如下:
为了处理播放器,我做了一个useEffect:
您将根据到目前为止创建的函数来管理状态“isPlaying”。
zqdjd7g95#
未捕获的类型错误:无法读取未定义的属性"setState"
出现这个错误是因为this关键字在JavaScript中的工作方式。我认为如果我们解决了这个问题,音频应该可以播放得很好。
如果你在
play()
中执行console.log(this)
,你会发现this
是未定义的,这就是为什么它会抛出那个错误,因为你在执行this.setState()
,基本上this
在play()
中的值取决于函数是如何调用的。1.使用bind()设置函数this的值,而不管它是如何调用的:
1.使用不提供自身此绑定的箭头函数
现在您将可以访问
play()
中的this.setState
和this.audio
,对于pause()
也是如此。ia2d9nvy6#
我来派对有点晚了,不过我还是背下了“托马斯·亨内斯”:
人们在研究这段代码时会遇到的一个问题是,如果你试图在一个有多个页面的应用中逐字逐句地使用这段代码,他们不会有一个愉快的时光,因为状态是在组件中管理的,你可以播放、导航和再次播放。
为了解决这个问题,您希望让组件将其状态推送到App.js并在那里管理状态。
请允许我说明我的意思。
我的播放器组件如下所示:
然后在我的App.js中,它看起来像这样(使用TODO列表示例应用程序):
8ftvxx2r7#
你可以试试这个,对我有用