はじめに
みなさんTwitchというゲームに特化した配信サイトはご存知でしょうか。Justin.tvからゲーム専用配信サイトとして派生し、現在はAmazon傘下にあるサイトです。今回はTwitchAPIとReactでランキングサイトを作成していこうと思います!
ゴール
以下のようなランキングサイトを作成していきたいと思います!!
※ 実際に動いているものがみたい方はこちらからご覧になれます。
TwtichAPIキーの取得
こちらからAPIキーの取得を行なってください。
ログインを行い下記の画像の赤枠の部分で囲んである**「アプリケーション登録」**から登録を行なってください。
名前は使用されていると使えないため、日付など入れて良しなにしましょう。リダイレクト先はローカル環境を指定することが可能のためlocalalhost:3000
にしました。下記の画像の赤枠で囲まれている部分がクライアントIDになります。以後使うため大切に保管してください。
create-react-app
今回はcreate-react-app
を使って雛形を作り、開発して行こうと思います。
※ create-react-app
が使えない方はnpm install -g create-react-app
でインストールしてください。
# create-react-app プロジェクト名
$ create-react-app twitch_ranking
create-react-app
コマンドでアプリの雛形の作成が完了したら、作成したディレクトリに移動し以下のコマンドを実行してください。(--save
オプションはpackage.jsonのdependenciesに追加するために行なっています。)prop-types
はpropsの型チェックする際に使います。@material-ui/core
はReactでマテリアルデザインを扱うためのUIコンポーネントです。今回はデザイン全般を@material-ui/coreを使って実装します。@material-ui/icons
アイコンを扱うUIコンポーネントです。使い勝手の良いアイコンがたくさんあるため今回もユーザーアイコンなど様々なアイコンを使います。
# prop-typesコンポーネントのインストール
$ npm install --save prop-types
# @material-ui/coreコンポーネントのインストール
$ npm install --save @material-ui/core
# @material-ui/iconsコンポーネントのインストール
$ npm install --save @material-ui/icons
Headerの作成
サイトのヘッダーを作成していきます。プロジェクト名/src
配下にHeader.js
ファイルを作成してください。サイトのヘッダーはシンプルにタイトルのみの表示となります。ヘッダーのデザインは公式のAppBarを参考にしています。
import React from 'react';
import PropTypes from 'prop-types';
import {withStyles} from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
const styles = {
root: {
width: '100%',
backgroundColor: '#6441a5',
},
};
const Header = (props) => {
const {classes} = props;
return (
<AppBar position="static" className={classes.root}>
<Toolbar>
<Typography variant="title" style={{color: '#E6E6E6'}}>Twitchランキング(JP)</Typography>
</Toolbar>
</AppBar>
);
};
Header.propTypes = {
// classesがobjectであるかチェック
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Header);
ランキングページの作成
次にランキングページの作成をします。プロジェクト名/src/App.js
を以下のようにしてください。ここではfetch
を用いてTwichAPIにGETリクエストを行なっています。header
のClient-ID
部分に先ほど取得したクライアントIDを入力してください。jsonを受け取る際にあらかじめ取得したjsonを格納する空の配列であるresp
をstateで用意します。Streamsコンポーネントでは取得したresp
内に格納されている配列をmap関数を用いて処理しています。最後に先ほど作成したヘッダーと組み合わせてあげればページの完成です。
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Header from './Header'
import Paper from '@material-ui/core/Paper'
import Typography from '@material-ui/core/Typography'
import GameIcon from '@material-ui/icons/Gamepad'
import ViewerIcon from '@material-ui/icons/Person'
// 後ほど作成する
import './twitch.css'
class TwitchRankPage extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
resp: [],
};
// 取得件数を50に設定する。
this.limit = 50
}
componentDidMount() {
fetch(`https://api.twitch.tv/kraken/streams/?language=ja&limit=${this.limit}`, {
method: 'get',
headers: new Headers({
'Accept': 'application/vnd.twitchtv.v5+json',
'Client-ID': '先ほど取得したクライアントID',
}),
})
.then((response) => response.json())
.then((resp) => {
this.setState({
resp: resp.streams,
loading: false,
})
})
.catch((error) => {
console.log("error", error)
})
}
render() {
const { resp } = this.state;
return (
<div>
<Header />
<Streams resp={resp} />
</div>
)
}
}
const Streams = (props) => {
const json = props.resp;
let i = 1;
return (
<Paper className="paper">
<table>
<thead className="table-head">
<tr>
<th className="rank"><Typography variant={"subheading"}>順位</Typography></th>
<th className="thumb"><Typography variant={"subheading"}>チャンネル</Typography></th>
<th className="movie-title" />
<th><Typography variant={"subheading"}>視聴者数</Typography></th>
</tr>
</thead>
<tbody>
{json.map((stream) => {
return (
<tr key={stream._id}>
<td className="rank">
<Typography variant={"title"}>{i++}</Typography>
</td>
<td className="thumb">
<a href={stream.channel.url}>
<img src={stream.preview.medium} alt={stream.channel.status} />
</a>
</td>
<td className="detail">
<Typography variant={"title"} className="movie-title">{stream.channel.status}</Typography>
<Typography variant={"subheading"}>{stream.channel.display_name}</Typography>
<Typography variant={"subheading"} className="game-cat">
<GameIcon className="game-icon" />
<a href={"https://www.twitch.tv/directory/game/" + stream.channel.status}>
{stream.game}
</a>
</Typography>
</td>
<td className="viewers">
<Typography variant={"title"}>
<ViewerIcon className="viewer-icon" />
{stream.viewers}
</Typography>
</td>
</tr>
)
})}
</tbody>
</table>
</Paper>
)
};
Streams.propTypes = {
rank: PropTypes.number,
userName: PropTypes.string,
movieTitle: PropTypes.string,
gameTitle: PropTypes.string,
viewers: PropTypes.number,
url: PropTypes.string,
thum: PropTypes.string,
};
export default TwitchRankPage
スタイルを整える
現在のままでは見栄えが悪いです。そのためプロジェクト名/src
配下にtwitch.css
を作成し、以下のようにしましょう。
/* PC */
@media screen and (min-width: 767px) {
root {
padding: 0;
margin: 0;
}
thead {
padding-bottom: 100px;
}
.paper {
text-align: center;
margin: auto;
margin-top: 30px;
width: 1000px;
}
table {
width: 1000px;
}
tr {
border-bottom: 1px solid #c9c9c9;
display: block;
padding-top: 10px;
padding-bottom: 10px;
}
.rank {
width: 80px;
}
.thumb {
padding: 0;
width: 320px;
}
.detail {
text-align: left;
width: 380px;
padding-left: 20px;
}
.movie-title {
width: 380px;
padding-right: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.game-cat {
width: 380px;
padding-left: 0;
padding-right: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.viewers {
padding-left: 20px;
width: 150px;
}
.viewer-icon {
padding-right: 10px;
color: #ff0000;
font-size: 30px;
position: relative;
top: 5px;
left: 5px;
}
.game-icon {
padding-right: 10px;
color: #380B61;
font-size: 25px;
position: relative;
top: 5px;
left: 5px;
}
}
/* SmartPhone */
@media screen and (max-width: 767px) {
table {
border-collapse: collapse;
border-spacing: 0;
width: 100vw;
border: none;
}
thead {
display: none;
}
tr {
padding-top: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #c9c9c9;
display: block;
}
td {
border-bottom: none;
display: block;
padding: 0;
}
.rank {
display: none;
}
img {
width: 100vw;
}
.detail {
padding-right: 0;
}
.movie-title {
width: 100vw;
padding-right: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.game-cat {
width: 380px;
padding-left: 0;
padding-right: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.viewers {
padding-right: 30px;
text-align: right;
}
.viewer-icon {
padding-right: 10px;
color: #ff0000;
font-size: 30px;
position: relative;
top: 5px;
left: 5px;
}
.game-icon {
padding-right: 10px;
color: #380B61;
font-size: 25px;
position: relative;
top: 5px;
left: 5px;
}
}
完成
最後にindex.js
にTwitchRankPageコンポーネントを追加してください。コンソールからnpm start
コマンドで実行して動いたら完成です。動かない方はエラーをよく読んでみてください。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import TwitchRankPage from './App';
ReactDOM.render(
<TwitchRankPage />,
document.getElementById('root')
);
まとめ
みなさんできましたでしょうか。cssなどを変更してかっこよくカスタマイズしてみてください。今回初めてTwitchAPIを使ってみましたが、充実していていろいろできそうに感じました。みなさんもTwichAPIを使って何か作ってみてはいかがでしょうか。