React tutorial(動画サイトの作り方)
以下の記事を参考に、Reactを用いた動画サイトを作っていきます。
機能としては
- ユーザーがサインアップしてログインできる
- ログインしたユーザーは、約20〜30秒の短い動画をアップロードできる。
- 未登録のユーザーは、ダッシュボード上のプラットフォームにアップロードされた、すべての動画を見ることができる。
- ユーザーはTwitterで、どの動画共有もできる。
以上の機能を備えたアプリとなるよう、作っていきます。
まず初めに、今回のtutorialもcreate react appを使用します。
また、public/index.htmlファイルに以下のコードを追加して、bootstrapを使用できるようにします
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">更にターミナルで以下のコードをうち、パッケージをインストールします。
npm install auth0-js react-router@3.0.0 jwt-decode axiossrc直下にutilsフォルダを作って、AuthService.jpにこのコードを貼り付けます。src/index.jsファイルにもこちらのコードを貼り付けます。
では、ここまでの設定を終えたら、実際にコンポーネントをつくっていきます。
今回、次の4つのコンポーネントを作成します。
- Callbackコンポーネント
基本的に認証情報を保存し、アプリ内のアップロードルートにリダイレクトします。 - Displayコンポーネント
すべての動画を表示するためのダッシュボードになります。 - Navコンポーネント
アプリ内のすべてのページが共有するナビゲーションです。 - Uploadコンポーネント
登録ユーザーによる動画のアップロードを処理します。
またindex.jsファイルのコードから
<Route path='' component=ComponentName>ReactrouterのRouteコンポーネントが各コンポーネントを呼んでいます。
では、各コンポーネント内を見ていきます。
component/Callback.js:
import { Component } from 'react';
import { setIdToken, setAccessToken } from '../utils/AuthService';
class Callback extends Component {
componentDidMount() {
setAccessToken();
setIdToken();
window.location.href = "/";
}
render() {
return null;
}
}
export default Callback;component/Nav.js
import React, { Component } from 'react';
import { Link } from 'react-router';
import { login, logout, isLoggedIn } from '../utils/AuthService';
import '../App.css';
class Nav extends Component {
render() {
return (
<nav className="navbar navbar-default">
<div className="navbar-header">
<Link className="navbar-brand" to="/">Miniflix</Link>
</div>
<ul className="nav navbar-nav">
<li>
<Link to="/">All Videos</Link>
</li>
<li>
{
( isLoggedIn() ) ? <Link to="/upload">Upload Videos</Link> : ''
}
</li>
</ul>
<ul className="nav navbar-nav navbar-right">
<li>
{
(isLoggedIn()) ? ( <button className="btn btn-danger log" onClick={() => logout()}>Log out </button> ) : ( <button className="btn btn-info log" onClick={() => login()}>Log In</button> )
}
</li>
</ul>
</nav>
);
}
}
export default Nav;component/Display.js
import React, { Component } from 'react';
import { Link } from 'react-router';
import Nav from './Nav';
import { isLoggedIn } from '../utils/AuthService';
import axios from 'axios';
class Display extends Component {
render() {
return (
<div>
<Nav />
<h3 className="text-center"> Latest Videos on Miniflix </h3>
<hr/>
<div className="col-sm-12">
</div>
</div>
);
}
}
export default Display;component/Upload.js
import React, { Component } from 'react';
import { Link } from 'react-router';
import Nav from './Nav';
class Upload extends Component {
render() {
return (
<div>
<Nav />
<h3 className="text-center">Upload Your 20-second Video in a Jiffy</h3>
<hr/>
<div className="col-sm-12">
<div className="jumbotron text-center">
<button className="btn btn-lg btn-info"> Upload Video</button>
</div>
</div>
</div>
);
}
}
export default Upload;Upload Videos
今回はCloudinary(cloud上でvideo management service)をつかって、動画の投稿できるデータベースを作ります。
public/index.html内に次のコードを加えます。
<script src="//widget.cloudinary.com/global/all.js" type="text/javascript"></script>また、Uploadコンポーネント内に以下のコードを書きます。
window.cloudinary.openUploadWidget(
//cloud_name, 'unsigned-preset'を各自のIDに書き換える { cloud_name: cloud_name',
upload_preset: 'unsigned-preset',
tags: ['miniflix'],
sources: ['local', 'url', 'google_photos', 'facebook', 'image_search']
},
function(error, result) {
console.log("This is the result of the last upload", result);
});
}
上記のコードでは、引数tagsを追加しています。
Cloudinyはこの引数をもって、自動でビデオにタグ付けします。
このアプリにアップロードされたすべての動画は自動的にタグ付けされ、さらに、必要な数だけタグを提供することができます。
Uploadコンポーネントのrender()内のアップロードボタンを以下の様に修正して、このボタンがクリックされた時に、cloudinary.openUploadWidgetが呼ばれる様にします。
<button onClick={this.uploadWidget} className="btn btn-lg btn-info"> Upload Video</button>Display Videos
次にDisplayコンポーネントを見ていきます。
まず、次のパッケージをインストールします。
yarn add cloudinary-reactまたDisplayコンポーネントに以下のコードを書きます。
state = { videos: [] };
getVideos() {
axios.get('http://res.cloudinary.com/unicodeveloper/video/list/miniflix.json')
.then(res => {
console.log(res.data.resources);
this.setState({ videos: res.data.resources});
});
}
componentDidMount() {
this.getVideos();
}上のgetVideo関数によって、Cloudinaryから、ある特定のタグのビデオデータを取ってくることが出来ます。
getVideoはcomponentDidMountの中で呼ばれていることから、Displayコンポーネントのrender()された直後に呼ばれます。
また、renderメソッド内では、単にビデオのstateをmapでループし、各ビデオのpublic_idをVideoコンポーネントに渡している処理だけとなっています。
Videoコンポーネントは、CloudinaryからビデオURLを取得し、WebページにHTML5ビデオ表示しています。
share on twitter
次のパッケージをインストールします。
yarn react-twitter-widgetscomponents/Display.jsに次のコードを書きます。
import { Share } from 'react-twitter-widgets'そして、videoを囲っている<div>に以下コードを書き加えたら
<Share url={`http://res.cloudinary.com/unicodeveloper/video/upload/${data.public_id}.mp4`} />twitter上でリンクをシェアできるようになります。
感想
React routerの動きをなんとなく分かった様な気がします。
コンポーネントを呼び出すことで、React内でページ遷移をしているような機能をしています。
しかし、実際に自分でコンポーネントをゼロから書いていけるかと言われると、まだかなり怪しい状態です。
また、Cloudinaryみたいなクラウドサービスを使えば、DataBaseを使う必要がないことに驚きました。
