JavaScript >> Javascript 文檔 >  >> React

自定義 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 上可用。

支持我

如果你想支持我,你可以點擊下面的鏈接給我買一杯咖啡(然後我可能會變成一個新的自定義掛鉤......☕)。


Tutorial JavaScript 教程
  1. 使用可移動可以做的 5 件事

  2. VueJs 路由器最重要的主題

  3. 問 DEV - 你有哪些鮮為人知的關於更清潔、更好的 JavaScript/TypeScript 的技巧?

  4. 在 ReactJS 中獲取視口/窗口高度

  5. 關於 React 18 你需要知道的一切

  6. 檢查發出變量的類型是否與自定義類型匹配

  7. 為什麼在 JS 中使用 Maps over Objects ?

  1. 使用 Angular 和 Nginx 構建多階段 Docker

  2. 我們需要 JS 開發人員

  3. 使用 Summaryze 輕鬆快速地為您的 forem(dev.to) 帖子創建摘要!

  4. 如何使用 JavaScript Fetch API 獲取 JSON 數據

  5. 如何使用 TypeScript 使用 Vue Composition API - 第 2 部分

  6. 快速提示:顯示瀏覽器通知的最簡單方法

  7. 如何從javascript中的字符串獲取月份?

  1. Twitter Bootstrap 3 – JavaScript 組件

  2. 使用 Vanilla JavaScript 實現簡單的 SPA 路由

  3. 是否應該允許用戶禁用 JavaScript?

  4. 商業支持是開源可持續性的可行方式嗎?