自定義 React Hooks:useAudio
在 Custom React Hooks 系列的最後一集中,我們發現了 useNetworkState hook 來簡化用戶的網絡狀態管理。今天,我們將探索另一個有用的自定義鉤子:useAudio
.準備好?走吧!
- 動機
- 實施
- 用法
- 結論
- 支持我
動機
為什麼你會需要這樣的鉤子?好吧,我給你舉兩個例子。第一個是我的個人網站,iamludal.fr(我發誓這不是自我推銷🙄),使用 React 構建,頂部導航欄包含一個按鈕,用於在明暗主題之間切換。實際上,如果你把聲音調大一點,你可能會聽到開關聲。這個聲音來自這個自定義的鉤子。第二個例子是 Typospeed 遊戲(也不是自我推銷),你可以在刪除單詞時聽到聲音(實際上,Typospeed 是用 Svelte 構建的,但你明白了)。在這兩個例子中,我們都需要播放一些聲音,我們不想通過手動實例化一個新的音頻、設置它的音量、它的播放速率來重複我們自己……
const Home = () => {
const audio = useRef(new Audio('/switch.mp3'))
useEffect(() => {
audio.current.playbackRate = 1.5
audio.current.volume = 0.8
}, [])
return (
<button onClick={audio.current.play}>Play Sound</button>
)
}
話雖如此,我們現在有充分的理由來實現我們的新自定義鉤子。讓我們把手弄髒! 👨🏻💻
實施
正如我們在上一部分中所說,我們不想重複自己(這是自定義鉤子的主要目標)。因此,我們的函數將為我們的音頻實例(可以是靜態的或動態的)採用可選參數,對應於其他選項。
const audio = useAudio('/switch.mp3', { volume: 0.8 })
另外,我們不想打擾 .current
屬性:我們必須在新鉤子中提取這個邏輯。這樣,我們將能夠直接與音頻實例進行交互。
audio.play()
audio.pause()
因此,骨架將如下所示:
const useAudio = (src) => {
const audio = useRef(new Audio(src))
return audio.current
}
這是鉤子的第一個基本版本。如果您不需要其他選項,那麼您就可以開始了。但是我們將向這個鉤子添加另一個參數:一個選項對象。每次該對象的給定屬性發生變化時,我們都必須更新我們的實例。這樣,選項可以從外部動態更新 - 使用另一個鉤子,例如 useState
.最終的鉤子實現現在看起來像這樣:
const useAudio = (src, { volume = 1, playbackRate = 1 }) => {
const audio = useRef(new Audio(src))
useEffect(() => {
audio.current.volume = volume
}, [volume])
useEffect(() => {
audio.current.playbackRate = playbackRate
}, [playbackRate])
return audio.current
}
我們的鉤子現在可以使用了。 🤘
用法
回到我們的第一個例子,代碼現在可以簡化如下:
const Home = () => {
const audio = useAudio('/switch.mp3', { volume: 0.8, playbackRate: 1.5 })
return (
<button onClick={audio.play}>Play Sound</button>
)
}
我們已經抽像出這個新鉤子中的所有邏輯,從而使代碼更簡單、更乾淨、更易讀。
結論
我希望這個鉤子對你的項目有用。如果您有任何問題,請隨時在評論部分提出。話雖如此,感謝您閱讀我的內容,我們下次見,為您提供新的自定義掛鉤。 🤗
源代碼 在 CodeSanbox 上可用。
支持我
如果你想支持我,你可以點擊下面的鏈接給我買一杯咖啡(然後我可能會變成一個新的自定義掛鉤......☕)。