WEB開発の門外漢がReactでお試しSPAを作成する
作成前
今までPythonでデータ分析とかスクレイピングのためのプログラムは書いてきた。
でも、WEB開発はあまりやってこなかった。
自分で何かWEBサービスを作ってみたいという思いがむくむくと湧いてきた。
少しずつWEB開発をやっていこう。
とりあえずサーバーサイドは脇に置いて、フロントエンドから取り掛かろう。
道具の選択
Javascriptのフロントエンドライブラリは、無難にReactを選択する。
React Nativeもあるので、将来的にはスマホアプリへの広がりも少し期待した。
いきなりゴリゴリと本格的にサービスを開発するわけにもいかない。
まずは何か見本ページをパクっ...真似てReactに慣れよう。
ここにReactで作成したWEBアプリがたくさんあるので、その中からこれを真似る。
CSSフレームワークはBootstrapが使われているようだ。
何作る
まんま見本サイトをパクってロボットの写真を使うのは趣がない。
ジャズのプレイヤーの写真に差し替えてみよう。
ジャズマン名鑑のようなものを作ろう。
何やりたい
「ページを変えた時に画面全体を再描画するのではなく、パネル内の文字と写真だけを描画する」という機能を実装してみたい。
実際に試作してみたSPAはこちら。
手を付けなかったもの
ゆくゆくは使ってみないといけないだろうが、今回は小規模な開発なのでFluxやReduxは使わない。
また、サーバー部分はとりあえず脇に置いているので、AWSとかは使わない。
デプロイがとても簡単にできるGithub Pagesを使う。
詰まったところ
作業はReact公式やReact本、Web上の情報を収集すれば、大体進めていける。
とはいえ、「現在のページをどのように管理するか、またページが変わったことをどのようにパネル部分のコンポーネントに伝えるか」で詰まった。
どうやら、この部分はReactでアプリを構築していく上で基礎の部分であり、これをきちんと理解できていないとWebアプリっぽい機能は全く実装できないようだ。
ページ管理
そもそもどのようにページを管理したいいのかが分からない。
React-Bootstrapの公式を眺めた。
どうやら、今何ページ目が開かれているかはコンポーネントが持つ内部状態で管理するらしい。
ちなみにコンポーネント間のデータの受け渡しについては、こちらのページに詳しく書いてある。
以下の手順でデータの受け渡しをやる。
- ページネーションのボタンがクリックされる。
- ページが変更されたことを、ページネーションの子コンポーネントからをページを管理している親コンポーネントに通知する
- 通知を受け、親コンポーネントが内部状態として持っている「activePage」を書き換える
- 親コンポーネントからパネル部分の子コンポーネントへページが変更されたことを通知する
- 変更されたページに属するジャズマンの写真と名前を描画する
親コンポーネントと子コンポーネント間の連携
Pageのコンポーネントと親コンポーネントの連携は以下のように行う。
- React-Bootstrapの
Pagination
コンポーネントを子コンポーネントとして配置 - 親コンポーネントのメソッドとして
activePage
を書き換えるイベントハンドラを定義 - そのイベントハンドラを
this.props
経由でPagination
コンポーネントへと渡し、onSelect
属性に代入
また、写真を描画するItems
コンポーネントの方と親コンポーネントの連携は以下のように行う。
親は以下のようなコードになる。
class Center extends Component { constructor(props) { super(props) this.state = { //ここで現在のページ数を管理する activePage: 1 } } //ページ数を書き換えるメソッド updateActivePage (e) { this.setState({activePage: e}) } render () { const activePage = this.state.activePage const updateActivePage = (e) => this.updateActivePage(e) return ( <Grid className="container-fluid"> <Title /> <Page activePage={activePage} //このようにしてPageコンポーネントにupdateActivePageを渡す updateActivePage={updateActivePage} /> //ItemコンポーネントにacitivePageの値を渡す <Items page={activePage} /> <Page activePage={activePage} //このようにしてPageコンポーネントにupdateActivePageを渡す updateActivePage={updateActivePage} /> </Grid> ) } }
ちなみに、子のPage
コンポーネントのこのようになっている。
Item
コンポーネントの方も値の受け取り方は同じである。
render(){ const pageNumber = Math.ceil(this.getPageNum() / 12) //親から受け渡されたupdateActivePage()はこのように受け取る。 const updateActivePage = this.props.updateActivePage return ( <Pagination prev next first last ellipsis boundaryLinks items={pageNumber} activePage={this.props.activePage} //SelectイベントによってactivePageを書き換えるようupdateActivePage()をセットする。 onSelect={(e) => updateActivePage(e)} />) }
最後に
SPAを作成したと言っても、これはまだ試作段階なので、不十分な点が色々とある。
色々と作っていって、Reactに早く慣れていきたい。