2018年5月17日

プログラミング

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

目次

  1. はじめに
  2. 発音させる
  3. Propsの値を使う
  4. まとめ

はじめに

Reactで簡単なサービスを作りながら、使い方を覚えていくシリーズの第3弾です。

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

前回は、ReactでSmart Speaker’s Command Speaker(SSCS)のインタフェースを作り、部分的にコンポーネント化しました。
今回は実際に発音させていく部分を作ります。

発音させる

前回まで作っていたのがこちらです。
 2018-05-17 7.13.53.png (95.9 kB)
カードにコマンドはちゃんと表示されていますが、特にクリックすることもできず、また発音もしてくれません。
このカードをクリックしたらコマンドが発音される部分を作っていきましょう。
src/components/speaker_button.js にまず、クリックイベントを作っていきます。

import React, { Component } from 'react';

export default class SpeakerButton extends Component {
  _onClick() {
    console.log("クリックされたよ");
  }

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

まずこちらで_onClick() を定義しています。

  _onClick() {
    console.log("クリックされたよ");
  }

そしてこちらでボタンがクリックされたら、_onClickを実行しています。

<button className="card" onClick={this._onClick}>

ここまではシンプルですね。
では、実際に発音させてみます。
ブラウザ上で発音させる為には、SpeechSynthesisUtterance という音声合成APIを使用します。

詳しくはMDNのリファレンスをご覧ください。

これだけで_onClickが実行されたらコマンドを発音してくれます。

  _onClick() {
    let ssu = new SpeechSynthesisUtterance();
    ssu.text = "音楽かけて"
    ssu.lang = 'ja-JP';
    speechSynthesis.speak(ssu);
  }

簡単に解説していきます。
let ssu = new SpeechSynthesisUtterance();
こちらでSpeechSynthesisUtteranceのインスタンスを作ります。

話す内容の設定をします。
ssu.text = "音楽かけて"

そして言語の設定をします。
ssu.lang = 'ja-JP';

最後に発音のコマンドを実行するだけです。
speechSynthesis.speak(ssu);

簡単ですね。
話す内容については、漢字でも正しく発音してくれますが、読み方次第では上手く発音してくれないので、場合によってはひらがなにしましょう。

これで、少しぎこちないですが「音楽かけて」とコマンドを発音してくれるようになりました。

Propsの値を使う

発音はできましたが、Alexaの場合には「アレクサ、」、Google Homeの場合には「OK, Google」とコマンド前につける必要があります。

なので、このコンポーネントのPropsの値を判定し、そこからコマンド前の「アレクサ、」「OK, Google、」という呼びかけ文言を発音してもらうようにしていきましょう。

src/app.js 上ではこのようにSpeakerButtonを使っていましたね。

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

そしてsrc/components/speaker_button.js ではこのようにしてpropsの値を取り出していました。
this.props.speaker_type

これを利用して条件分岐していきましょう。

これでどうでしょうか。この先様々なスピーカーが出てくると考え、ifではなくswitchで条件を書いています。

  _onClick() {
    let ssu = new SpeechSynthesisUtterance();
    let pre_commands = '';
    switch (this.props.speaker_type) {
      case 'alexa': {
        pre_commands = "Alexa、";
        break;
      }
      case 'google': {
        pre_commands = "OK, Google、";
        break;
      }
      default:
      break;
    }
    ssu.text = `${pre_commands}音楽かけて`
    ssu.lang = 'ja-JP';
    speechSynthesis.speak(ssu);
  }

POINT!!

`${pre_commands}音楽かけて` としているところは、JavaScriptのテンプレートリテラルを使用しています。
従来であれば pre_command + “音楽かけて” としなければいけなかったことを、すっきりとかけるようになっています。”#{pre_commands}音楽かけて” のように書くRubyなどの式展開と似ていますね。

さて、これでOKかと思いきや、このようなエラーが表示されます。

 2018-05-17 13.09.39.png (41.5 kB)

TypeError: Cannot read property 'props' of undefined
エラーメッセージの通り、propsが定義されていないよというメッセージです。

なぜこうなるのでしょうか。
ポイントはthis です。

thisをbindさせよう

実はthisは呼ばれ方によって値が変わってきます。
要はどの時点のthisなのかによって値が変わってくる、という扱いが難しいものなのです。

そこでES5(ECMAScript 5というJavaScriptの言語仕様のバージョン)では、bindというthisの値を拘束してしまうメソッドが使われるようになりました。
更に、ECMAScript 2015ではより便利にしたアロー関数というものが使われるようになりました。

ちょっと一言

bindが導入される以前は、thisの値を一時的に_thisやthatに格納する、などで対応することが多くありました。。thisをthatに入れる(「これ」を「あれ」に入れる)というのは、ちょっとよくわかりづらいですね。

では、早速使い方を見ていきましょう。
MDNのアロー関数の例を見ると、このようにあります。
(param1, param2, …, paramN) => { statements }

// 引数がない場合、丸括弧を書かねばいけません:
() => { statements }

今回の場合、引数はない為にこのようになります。
onClick={() => this._onClick()}

ちょっとわかりにくいかもしれませんが、onClickイベントのときに実行される関数として、onClickを実行する際のthisをbindし、この呼び出す時点のthisを_onClickに渡しています
なので、これで_onClickの中で this.props.speaker_type が使えるようになります。

さて、これでGoogle HomeとAlexaどちらで実行しても正しくコマンドを発音してくれるようになりました!

最終的にはこちらのコードとなりました。
src/components/speaker_button.js

import React, { Component } from 'react';

export default class SpeakerButton extends Component {
  _onClick() {
    let ssu = new SpeechSynthesisUtterance();
    let pre_commands = '';
    switch (this.props.speaker_type) {
      case 'alexa': {
        pre_commands = "alexa";
        break;
      }
      case 'google': {
        pre_commands = "OK Google";
        break;
      }
      default:
      break;
    }
    ssu.text = `${pre_commands}、音楽かけて`
    ssu.lang = 'ja-JP';
    speechSynthesis.speak(ssu);
  }

  render() {
    return (
      <div className="col-sm-6 mb-2 mt-2">
        <button className="card" onClick={() => this._onClick()}>
          <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>
    );
  }
}

まとめ

今回は発音部分のロジックを作りました。
またアロー関数を使用し、thisをbindしメソッド呼び出しをできるようにもしました。

ですが、当然コマンドは音楽をかけるもの以外にもたくさんあります。
そして1個1個ロジックを作っていくのは大変です。

なので次回はコマンドをデータ化したファイルを用意し、そこから読み込みコマンドを一覧表示させる処理を作っていきます。

Reactのお仕事に関するご相談

Bageleeの運営会社、palanではReactに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。

無料相談フォームへ

0

0

AUTHOR

eishis

Eishi Saito 総務

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

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

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

簡単に自分で作れるWebAR

「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。

palanARへ
palanar

palanはWebARの開発を
行っています

弊社では企画からサービスの公開終了まで一緒に関わらせていただきます。 企画からシステム開発、3DCG、デザインまで一貫して承ります。

webar_waterpark

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

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

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

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

sasakki デザイナー

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

yamakawa

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

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

Sayaka Osanai デザイナー

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

はらた

はらた エンジニア

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

kobori

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

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

sasai

ささい エンジニア

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

damien

Damien

WebAR/VRの企画・開発をやっています。森に住んでいます。

ゲスト bagelee

ゲスト bagelee

かっきー

かっきー

まりな

まりな

suzuki

suzuki

miyagi

ogawa

ogawa

雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと

いわもと

デザイナーをしています。 好きな食べ物はラーメンです。

kobari

taishi kobari

フロントエンドの開発を主に担当してます。Blitz.js好きです。

shogokubota

kubota shogo

サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!

nishi tomoya

aihara

aihara

グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。

nagao

SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

kainuma

Kainuma

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

sugimoto

sugimoto

asama

ando

iwasawa ayane

oshimo

oshimo

異業界からやってきたデザイナー。 palanARのUIをメインに担当してます。 これからたくさん吸収していきます!

CONTACT PAGE TOP