使用React Hooks 實作一個 Music Player
此筆記將會記錄學到的技巧與不清楚的知識點。
建置環境
1
| npx create-react-app music-player
|
刪除不會用到的檔案。
- logo.svg
- setupTest.js
安裝Scss
Reset 頁面
1 2 3 4 5
| *{ margin:0; padding:0; box-sizing:border-box; }
|
這裡的筆記將會以commit 紀錄來呈現。
資料夾結構
Song Components
- 元件內都需要
return
- 最後需要
export default
1 2 3 4 5 6 7 8 9 10 11 12 13
| import React from "react";
const Song = ({ currentSong }) => { return ( <div className="song-container"> <img alt={currentSong.name} src={currentSong.cover}></img> <h2>{currentSong.name}</h2> <h3>{currentSong.artist}</h3> </div> ); }
export default Song;
|
這邊的小眉角是播放音樂的滾動條可以使用 input
這個 tag
,將 type
設成 range
就可以使用。
1
| <input min={0} max={songInfo.duration || 0} type="range" />
|
查看更多關於input的樣式
新增 Fontawesome
安裝Fontawesom
1 2 3
| npm i --save @fortawesome/fontawesome-svg-core npm install --save @fortawesome/free-solid-svg-icons npm install --save @fortawesome/react-fontawesome
|
匯入與設定大小
import
1 2 3 4
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPlay,faAngleLeft,faPause } from "@fortawesome/free-solid-svg-icons";
|
tag
- icon 設定icon
- size 可以控制大小,使用2x。
- color 可以控制顏色
1
| <FontAwesomeIcon onClick={playSongHandler} className="play" size="2x" icon={isPlaying ? faPlay : faPause}/>
|
建立 Music 的 Data
這邊會使用到 uuid,那麼uuid是什麼呢?
他是通用唯一辨識碼,在React中操作資料時,都需要一個key,且這個key不能與別的key重複,所以這裡就可以使用 uuid,產生辨識碼。
而uuid的辨識碼,可以到線上的產生器查看,長的會像下圖
安裝uuid後,就可以直接放在資料裡。
完整的資料連結,音樂內容從 Chillhop 這個網站取得資料。
使用 useState 取得音樂資料
因為 data 裡有寫 return
,所以直接執行data這個 function
,就可以取得資料。
1
| const [songs, setSongs] = useState(data());
|
- 使用 useState 取得當前的音樂(
currentSong
)與所有的音樂資料(songs
)。
- 再將當前的音樂,傳入songs components。
- 將值傳入song componets之後,再將資料依序取出來。
小技巧
將大張的圖片變成小圓
1 2 3 4
| img{ width: 20%; border-radius: 50%; }
|
- 引入 useRef
1
| import React,{useRef} from "react";
|
- 宣告
audioRef
為 useRef,初始值為null。
1
| const audioRef = useRef(null);
|
- 再將
audioRef
使用 ref 傳入 audio。
1
| <audio ref={audioRef} src={currentSong.audio}></audio>
|
- 傳入之後,就可以宣告函式,查看是否有取得資料。
1 2 3
| const playSongHandler = () =>{ console.log(audioRef.current); }
|
- 再將此函式綁到play 的 icon上
1
| <FontAwesomeIcon onClick={playSongHandler} className="play" size="2x" icon={faPlay}></FontAwesomeIcon>
|
- 使用 useState 控制播放狀態
1
| const [isPlaying,setIsPlaying] = useState(false);
|
- 再將資料傳入 Player 元件
1 2 3 4 5 6
| return ( <div className="App"> <Song currentSong={currentSong}/> <Player setIsPlaying={setIsPlaying} isPlaying={isPlaying}currentSong={currentSong}/> </div> )
|
- 傳入後,再使用 true or false判斷狀態。
1 2 3 4 5 6 7 8 9 10 11 12 13
| const Player = ({currentSong,setIsPlaying,isPlaying}) => { const audioRef = useRef(null); const playSongHandler = () =>{ if(isPlaying){ audioRef.current.pause(); setIsPlaying(!isPlaying); }else{ audioRef.current.play(); setIsPlaying(!isPlaying); } }
|