2018年5月14日

プログラミング

Reactでスマートスピーカーのコマンド発音サービスを作ろう(2)【作りながら覚えるReact】

目次

  1. はじめに
  2. UIを作っていく
  3. コンポーネントを追加する
  4. Propsを渡す
  5. まとめ

 

はじめに

Reactの基本をサービスを作りながら学んでいくシリーズの第二回!
前回はCreate React Appを使い、スマートスピーカーの発音サービス(Smart Speaker’s Commands Speaker)を作っていきました。

Reactでスマートスピーカーのコマンド発音サービスを作ろう(1)【作りながら覚えるReact】


今回はJSXを使用しUIを作っていきます。
また、コンポーネントを追加する方法もご紹介します。

_2018-05-07 14.28.20.png (106.5 kB)

UIを作っていく

前回はBootstrapとFont AwesomeをCDNから呼び出しましたね。
今回はそれらを使用し、JSXでデザインを作っていきます。

src/app.js

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  render() {
    return (
      <div>
        <div className="bg-dark">
            <div className="container">
              <div className="row">
                <div className="col-sm-2 col-md-2 py-3">
                  <h4 className="text-white">
                  <i className="fas fa-microphone"></i>
                     SSCS
                  </h4>
                </div>
                <div className="col-sm-10 col-md-10 py-3">
                  <p className="text-white">スマートスピーカーのコマンド発音代行サービス</p>
                </div>
              </div>
            </div>
          </div>
        <div className="jumbotron">
          <header className="text-center">
            <h2>Smart Speaker's Commands Speaker (SSCS)</h2>
            <p>スマートスピーカーのコマンドを日本語で発音して代行してくれるサイトです。コマンドをクリックすると発音されます。<br/>
              コマンドの追加は<a href="https://github.com/eishis/smart-speakers-commands-speaker" target="_blank" rel="noopener noreferrer">こちらから</a>お願いします。
            </p>
          </header>
        </div>
        <div className="container">
          <div className="row">
            <div className="col-sm-6 mb-2 mt-2">
              <h2><i className="fab fa-amazon"></i> Alexa</h2>
              <div className="row">
                <div className="col-sm-6 mb-2 mt-2">
                  <button className="card">
                    <div className="card-body">
                      <h4 className="card-title text-left">
                        <i className="fas fa-play"></i> 
                        音楽かけて
                      </h4>
                      <p className="card-text text-left">
                        ランダムで音楽をかけてくれるコマンドです。
                      </p>
                    </div>
                  </button>
                </div>
              </div>
            </div>
            <div className="col-sm-6 mb-2 mt-2">
              <h2><i className="fab fa-google"></i> Google Home</h2>
              <div className="row">
                <div className="col-sm-6 mb-2 mt-2">
                  <button className="card">
                    <div className="card-body">
                      <h4 className="card-title text-left">
                        <i className="fas fa-play"></i> 
                        音楽かけて
                      </h4>
                      <p className="card-text text-left">
                        ランダムで音楽をかけてくれるコマンドです。
                      </p>
                    </div>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default App;

基本的にHTMLとほぼ同じような形で書いています。
classではなくclassNameであるところがポイントです。

これでコマンドを1つずつ追加していけば、一応はUIは出来上がりそうですね。

コンポーネントを追加する

これでもUIは問題なさそうですが、1つずつコマンドを追加していくのは大変そうです。

また、 前回 の記事にあったReactの特徴として Component-Based の説明として「コンポーネントは再利用することができ、より効率的なUI構築を可能にします。」とありました。
このコマンドを表示する部分については、コンポーネントを使用することで再利用していくのが良さそうですね。

ディレクトリ

Reactのディレクトリ構成については好みもありますが、今回はsrcの下にcomponentsというディレクトリを作り、その中に共通のパーツを入れていきましょう。
speaker_button.js というファイルを作っていきます。

src/components/speaker_button.js

import React, { Component } from 'react';

export default class SpeakerButton extends Component {
  render() {
    return (
      <div className="col-sm-6 mb-2 mt-2">
        <button className="card">
          <div className="card-body">
            <h4 className="card-title text-left">
              <i className="fas fa-play"></i> 
              音楽かけて
            </h4>
            <p className="card-text text-left">
              ランダムで音楽をかけてくれるコマンドです。
            </p>
          </div>
        </button>
      </div>
    );
  }
}

前回学んだJSXですね。
app.jsで2回呼び出されていたコマンド発音ボタンについて、共通化しコンポーネント化しました。

AlexaとGoogle Homeでコマンドが異なるケースがありますが、その対策として後ほどpropsを使っていきます。

では、このコンポーネントをapp.jsから呼び出してみましょう。
とはいっても何も難しいことはなく、importで先程のコンポーネントから、exportしていたクラス名であるSpeakerButtonを呼び出すだけです。

import React, { Component } from 'react';
import './App.css';
import SpeakerButton from './components/speaker_button';

class App extends Component {
  render() {
    return (
      <div>
        <div className="bg-dark">
            <div className="container">
              <div className="row">
                <div className="col-sm-2 col-md-2 py-3">
                  <h4 className="text-white">
                  <i className="fas fa-microphone"></i>
                     SSCS
                  </h4>
                </div>
                <div className="col-sm-10 col-md-10 py-3">
                  <p className="text-white">スマートスピーカーのコマンド発音代行サービス</p>
                </div>
              </div>
            </div>
          </div>
        <div className="jumbotron">
          <header className="text-center">
            <h2>Smart Speaker's Commands Speaker (SSCS)</h2>
            <p>スマートスピーカーのコマンドを日本語で発音して代行してくれるサイトです。コマンドをクリックすると発音されます。<br/>
              コマンドの追加は<a href="https://github.com/eishis/smart-speakers-commands-speaker" target="_blank" rel="noopener noreferrer">こちらから</a>お願いします。
            </p>
          </header>
        </div>
        <div className="container">
          <div className="row">
            <div className="col-sm-6 mb-2 mt-2">
              <h2><i className="fab fa-amazon"></i> Alexa</h2>
              <div className="row">
                <SpeakerButton>
                </SpeakerButton>
              </div>
            </div>
            <div className="col-sm-6 mb-2 mt-2">
              <h2><i className="fab fa-google"></i> Google Home</h2>
              <div className="row">
                <SpeakerButton>
                </SpeakerButton>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

export default App;
<SpeakerButton>
</SpeakerButton>

発音ボタン部分がだいぶコンパクトになりましたね。

Propsを渡す

先程補足でも記載しましたが、今のところだとSpeakerButton内では、Google Homeなのか、Alexaのボタンなのかという情報がわかりません。
ですが、実際に発音する際にはGoogle HomeとAlexaでは呼びかけのセリフが異なりますし、そもそもコマンドが異なってくるケースがあります。

まず、AlexaのSpeakerButtonなのかGoogle HomeのSpeakerButtonなのかがわかるようにする必要がありそうです。

そんなときはPropsを使用します。

Propsとは

Propsは、コンポーネント呼び出し時に設定する属性値(情報)です。当然、呼び出されたコンポーネントの中でも属性値を参照することができます。
また、値については一回値を設定した後は変更ができない、という性質を持っています。

つまり、今回のケースだとApp.js内からSpeakerButtonを利用する際にPropsを設定することができますが、子コンポーネント内でPropsの書き換えはできません。(参照はできる)

具体的な使い方としては、
<コンポーネント Props名= 値>
のような形で設定します。

例えば今回のような場合だと、このようになります。

<SpeakerButton speaker_type="alexa">
</SpeakerButton>
<SpeakerButton speaker_type="google">
</SpeakerButton>

speaker_typeにalexa(google)を設定しSpeakerButtonコンポーネントを呼び出しています。

呼び出された側では、this.props.Props名で取り出すことができます。
今回の場合this.props.speaker_typeでalexaかgoogleかの値を取得します。

speaker_button.js でこのようにspeaker_typeの値を表示させてみましょう。

<h4 className="card-title text-left">
  <i className="fas fa-play"></i> 
  {this.props.speaker_type}音楽かけて
</h4>

すると、こちらのようにPropsとして指定したspeaker_typeが表示されるはずです。
 2018-05-13 0.57.24.png (40.4 kB)

JSX内では中括弧{}で囲むことでJavaScriptの式を中に書くことができます。

まとめ

今回はJSXでUIを作っていきました。
また共通部分をコンポーネント化し、コードをすっきりさせ、Propsの渡し方も解説していきました。
次回はコマンドの表示部分とデータ部分を分割し、実際に発音もさせていきます。

0

0

AUTHOR

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

しまだ

しまだ デザイナー

WebAR/VRのデザインと3DCG制作がメインです。 肩書きは「アニメ案件に関わりたいデザイナー」。

Miu マーケター

ドイツでWEBマーケティングしています。

しんのき エンジニア

主に React Native を使ったアプリ開発と AWS や Firebase を使ったサーバーレスアーキテクチャを担当しています。元々はインフラとかPHPをやっていました。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReact NativeやReact360をよく触っています。

furuya エンジニア

サーバーサイド、フロントエンド、Unityと色々手を出してる雑食系エンジニア。ReactNativeが最近のマイブーム。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

うえまつゆい エンジニア

サーバーサイドエンジニアからフロントエンドエンジニアになりました。主にReact Nativeでのアプリ開発をしています。

kobori

こぼり ともろう エンジニア

サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

sasai

ささい エンジニア

フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

damien

Damien

WebAR/VRを中心に企画やディレクションやエンジニアもちょっとやっています。森に住んでいます。

デザイナーゲスト

ゲスト デザイナー

CONTACT PAGE TOP