Cuộc hành trình học React/Redux đã gần đến hồi kết. Bài viết này sẽ hướng dẫn cách lấy dữ liệu từ SoundCloud API và xây dựng một music player đơn giản. Nào mình cùng lên xe buýt, bắt đầu hành trình khám phá!
Danh sách nhạc trên soundcloud
Fetch Dữ Liệu và Hiển Thị
Sau khi đã authenticated với SoundCloud API, bước tiếp theo là lấy dữ liệu bài hát về và hiển thị.
Đầu tiên, cần tham khảo API docs của SoundCloud để xác định API endpoint cho việc tải danh sách bài hát của người dùng. Sau khi authentication thành công, chúng ta sẽ gọi API này và cập nhật dữ liệu thông qua action setTracks
.
Trong file actions/auth.js
, thêm các thành phần để lấy danh sách bài hát:
// ...
import { setTracks } from '../actions/track';
// ...
export function auth() {
return (dispatch) => {
SoundCloud.connect().then((session) => {
dispatch(fetchMe(session));
dispatch(fetchTracks(session));
});
}
}
// ...
function fetchTracks(session) {
return (dispatch) => {
fetch(`${API_HOST}/me/activities?limit=20&offset=0&oauth_token=${session.oauth_token}`)
.then((res) => res.json())
.then((data) => {
dispatch(setTracks(data.collection));
});
}
}
Chúng ta sẽ gọi API activities
và lấy 20 phần tử đầu tiên. fetchTracks
sẽ được thực hiện asynchronous cùng với fetchMe
(lấy thông tin người dùng) sau khi authentication thành công.
Chỉnh Sửa Presenter và Tạo Component Track
Vì dữ liệu từ API thực tế khác với dữ liệu hard code ban đầu, chúng ta cần chỉnh sửa presenter của TrackList
. Để tiện lợi hơn, ta sẽ tách phần hiển thị track thành một component mới tên là Track
trong file components/TrackList/Track.js
:
import React, { PropTypes, Component } from 'react';
export default class Track extends Component {
static propTypes = {
track: PropTypes.object.isRequired
}
render() {
const { origin: { artwork_url, title } } = this.props.track;
return (
<div>
<img src={artwork_url} alt={`Bìa album bài hát ${title}`} />
<button onClick={this._play.bind(this)}>Play</button> {/* Nút play được thêm vào đây */}
{title}
</div>
)
}
}
Component này nhận prop là track
và hiển thị artwork, title, và nút play của bài hát.
Xây Dựng Music Player
Để phát nhạc khi nút Play
được click, chúng ta sẽ sử dụng tag Audio
của HTML5. Vì không nên đặt tag này trong mỗi Track
, chúng ta sẽ đặt nó ở higher order component là TrackList
.
Trong file TrackList.js
, thêm tag audio
:
// ...
render() {
// ...
return (
<div>
{/* ... */}
<audio id='player' ref={(player) => { this.player = player; }} src={activeTrack ? `${activeTrack.origin.stream_url}?client_id=${this.props.clientId}` : ''} ></audio> {/* activeTrack được kiểm tra trước khi sử dụng */}
{/* ... */}
</div>
);
}
// ...
Thêm State activeTrack
Để biết track nào đang được chơi, ta cần một state activeTrack
trong reducer tracks
. State này sẽ được cập nhật bởi action playTrack
.
Trong file reducers/tracks.js
, thêm state activeTrack
và action TRACK_PLAY
:
import {ActionTypes} from '../core/constants';
const initialState = {
tracks: [],
activeTrack: null
};
export default function(state = initialState, action) {
switch (action.type) {
case ActionTypes.SET_TRACKS:
return {...state, tracks: action.tracks};
case ActionTypes.TRACK_PLAY:
return {...state, activeTrack: action.track}
default:
return state;
}
}
Trong file actions/track.js
, thêm action playTrack
:
// ...
export function playTrack(track) {
return {
type: ActionTypes.TRACK_PLAY,
track
};
}
Kết Nối Action với Component
Thêm action playTrack
vào @connect
của TrackList
và truyền xuống Track
. Trong Track
, khi nút Play được click sẽ gọi action playTrack
.
// ... Track.js
_play() {
this.props.play(this.props.track.origin);
}
// ...
Phát Nhạc
Cuối cùng, trong componentDidUpdate
của TrackList
, chúng ta sẽ kiểm tra activeTrack
. Nếu có, gọi hàm play()
của audio
tag để phát nhạc.
// ...TrackList.js
componentDidUpdate() {
if(this.props.tracks.activeTrack){
this.player.src = `${this.props.tracks.activeTrack.stream_url}?client_id=${this.props.clientId}`;
this.player.play();
}
}
//....
Vậy là chúng ta đã hoàn thành việc xây dựng một music player đơn giản với React/Redux.
Tài liệu tham khảo:
https://www.robinwieruch.de/the-soundcloud-client-in-react-redux/