无法在 ReactJs 中使用 setState 方法播放不同的歌曲
Unable to play a different song using setState method in ReactJs
// TuneContainer.js
import React, {useState} from 'react'
import './TuneContainer.css'
function TuneContainer(props) {
const[isPlaying, setIsPlaying] = useState(false)
const[isPaused, setIsPaused] = useState(true)
const audio = document.querySelector('audio')
const audioControls = () => {
if(isPaused) {
console.log(isPlaying)
console.log(isPaused)
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
console.log(isPlaying)
console.log(isPaused)
audio.play()
} else {
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
audio.pause()
}
}
return (
<>
<div className="tune-container">
<div className="info-class">
<img src={props.imgsrc} className="tune-img" alt={props.imgalt} onClick={audioControls}></img>
<audio src={props.audiosrc} id="tune" loop hidden></audio>
</div>
</div>
</>
)
}
export default TuneContainer
以上是包含图片的容器的代码,点击它会无限循环播放歌曲,直到点击图片再次暂停。下面给出的是调用 TuneContainer 并向其传递道具的主页。
// HomePage.js
import React from 'react'
import NavigationBar from './NavigationBar'
import TuneContainer from './TuneContainer'
import Bird from '../images/Bird.svg'
import BirdWhistling from '../audios/Bird-whistling.mp3'
import Leaves from '../images/Leaves.svg'
import LeavesRustling from '../audios/Rustling-leaves.mp3'
function HomePage() {
return (
<>
<NavigationBar />
<div className="container">
<TuneContainer audiosrc={BirdWhistling} imgsrc={Bird} imgalt="Bird by Ana María Lora Macias from the Noun Project"/>
<TuneContainer audiosrc={LeavesRustling} imgsrc={Leaves} imgalt="leaves by KP Arts from the Noun Project"/>
</div>
</>
)
}
export default HomePage
所以在这里,当我点击小鸟图像时,我听到了鸣叫声,因为这些是通过的道具。第二个 TuneContainer 具有完全不同的图像和音频。但是,当点击树叶图像时,它仍然播放叽叽喳喳的声音。所以我相信音频源没有正确更新。有人可以强调我哪里做错了吗?
P.S: 在有人问之前,我已经正确检查了所有的路径和文件名,没有,两个音频文件中的歌曲不同他们。
虽然我知道 SO 强烈建议一个问题问一个问题 post,但我将在此处添加我的第二个问题,因为它高度相关并且不需要额外的代码。
问: 当我检查控制台时,打印的值(由于 console.log
语句)是 false, true, false, true
。我相信它应该打印 false, true, true, false
,因为我在 setState 函数之前和之后打印一次。为什么会有这样的行为?
因为 document.querySelector('audio')
总是 return 第一个 html 音频元素,在您的例子中是鸟鸣声。
您可以为每个 TuneContainer
使用唯一的 (id) 标识符。在您的音频标签上使用该 ID 并查询 select 该 ID,这将指向正确的音频元素。
另一种方法是使用 useRef
获取音频元素。
// TuneContainer.js
...
const audioRef = React.useRef(null);
/* const audio = document.querySelector('audio') */
const audioControls = () => {
if(isPaused) {
console.log(isPlaying)
console.log(isPaused)
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
console.log(isPlaying)
console.log(isPaused)
// audio.play()
audioRef.current.play();
} else {
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
// audio.pause()
audioRef.current.pause();
}
};
...
...
return (
...
...
<audio ref={audioRef} src={props.audiosrc} id="tune" loop hidden></audio>
...
);
// TuneContainer.js
import React, {useState} from 'react'
import './TuneContainer.css'
function TuneContainer(props) {
const[isPlaying, setIsPlaying] = useState(false)
const[isPaused, setIsPaused] = useState(true)
const audio = document.querySelector('audio')
const audioControls = () => {
if(isPaused) {
console.log(isPlaying)
console.log(isPaused)
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
console.log(isPlaying)
console.log(isPaused)
audio.play()
} else {
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
audio.pause()
}
}
return (
<>
<div className="tune-container">
<div className="info-class">
<img src={props.imgsrc} className="tune-img" alt={props.imgalt} onClick={audioControls}></img>
<audio src={props.audiosrc} id="tune" loop hidden></audio>
</div>
</div>
</>
)
}
export default TuneContainer
以上是包含图片的容器的代码,点击它会无限循环播放歌曲,直到点击图片再次暂停。下面给出的是调用 TuneContainer 并向其传递道具的主页。
// HomePage.js
import React from 'react'
import NavigationBar from './NavigationBar'
import TuneContainer from './TuneContainer'
import Bird from '../images/Bird.svg'
import BirdWhistling from '../audios/Bird-whistling.mp3'
import Leaves from '../images/Leaves.svg'
import LeavesRustling from '../audios/Rustling-leaves.mp3'
function HomePage() {
return (
<>
<NavigationBar />
<div className="container">
<TuneContainer audiosrc={BirdWhistling} imgsrc={Bird} imgalt="Bird by Ana María Lora Macias from the Noun Project"/>
<TuneContainer audiosrc={LeavesRustling} imgsrc={Leaves} imgalt="leaves by KP Arts from the Noun Project"/>
</div>
</>
)
}
export default HomePage
所以在这里,当我点击小鸟图像时,我听到了鸣叫声,因为这些是通过的道具。第二个 TuneContainer 具有完全不同的图像和音频。但是,当点击树叶图像时,它仍然播放叽叽喳喳的声音。所以我相信音频源没有正确更新。有人可以强调我哪里做错了吗?
P.S: 在有人问之前,我已经正确检查了所有的路径和文件名,没有,两个音频文件中的歌曲不同他们。
虽然我知道 SO 强烈建议一个问题问一个问题 post,但我将在此处添加我的第二个问题,因为它高度相关并且不需要额外的代码。
问: 当我检查控制台时,打印的值(由于 console.log
语句)是 false, true, false, true
。我相信它应该打印 false, true, true, false
,因为我在 setState 函数之前和之后打印一次。为什么会有这样的行为?
因为 document.querySelector('audio')
总是 return 第一个 html 音频元素,在您的例子中是鸟鸣声。
您可以为每个 TuneContainer
使用唯一的 (id) 标识符。在您的音频标签上使用该 ID 并查询 select 该 ID,这将指向正确的音频元素。
另一种方法是使用 useRef
获取音频元素。
// TuneContainer.js
...
const audioRef = React.useRef(null);
/* const audio = document.querySelector('audio') */
const audioControls = () => {
if(isPaused) {
console.log(isPlaying)
console.log(isPaused)
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
console.log(isPlaying)
console.log(isPaused)
// audio.play()
audioRef.current.play();
} else {
setIsPlaying(!isPlaying)
setIsPaused(!isPaused)
// audio.pause()
audioRef.current.pause();
}
};
...
...
return (
...
...
<audio ref={audioRef} src={props.audiosrc} id="tune" loop hidden></audio>
...
);