思い込みで突破

インフラエンジニアぽい人の雑記

React Hooks 副作用フックに入門してみた

今回はReact Hooksの副作用(effect)フックについて学習しました。 前回はこちら。 tosyan-samoarinan.hatenablog.com

今回は以下のReact公式ドキュメントを参考にしています。 ja.reactjs.org

実装サンプル

まずReactのドキュメントをもとに実装しました。 タブに表示されるタイトルにカウントが表示されました。  f:id:tosyan_samoarinan:20191203230926p:plain

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

function App() {
  const [count, setCount] = useState(0);
  const [second_count, setSecondCount] = useState(0);
  const [second_text, setCountText] = useState({text:"Help! Push Second Button"});

  const onclickFunction = () => {
    setSecondCount(second_count + 1);
    setCountText({text:"Thank you for putting button!!!!"})
  }

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
  <div className="App">
      <header className="App-header">
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
          Click me
        </button>
        <p>
          {second_text.text}.
          Yout clicked {second_count} times
        </p>
        <button onClick={onclickFunction}>
          Click me.Second button
        </button>
      </header>
    </div>
  );
}

export default App;

副作用フックとは

そもそも副作用とは、ですが以下の記事が詳しいです。 英語でside effectです。

  1. 引数以外の要因で結果が変わってしまう関数
  2. 関数の外に影響を与えてしまう関数
    (中略)
    Reactにおいて具体的にはどのような処理が副作用であるかというと DOMを変更する APIとの通信 console.log setState() 変数への代入 などです。 Reactにおける「副作用」とは? - Qiita

まずは関数コンポーネント外にも影響を与えるものと理解しました。 サンプルプログラムでは、document.titleを変更する際に利用しています。 DOMはドキュメントオブジェクトモデルの略でHTML、XMLの要素を操作する仕組みです。 document.titleはHTMLのtitleタグのため、DOMを変更するのに副作用フックを使用しています。

クリーンアップを必要としない副作用

クラスを使った例は以下の通りです。(ドキュメントと同じです)

import React from 'react';
import './App.css';

class App extends React.Component {
  constructor(props){
    super(props);
    this.state = { 
      count: 0
    };
  }
  
  componentDidMount(){
    document.title = `You clicked ${this.state.count} times`;
  }
  componentDidUpdate(){
    document.title = `You clicked ${this.state.count} times`;
  }
  
    render(){
      return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1})}>
          Click me
        </button>
      </div>
      );
    }
  }
export default App;

f:id:tosyan_samoarinan:20191204232937p:plain

Reactドキュメントのサンプルプログラムでは、クラスの場合componentDidMount,componentDidUpdateを使用しており、クラスコンポーネントのrenderメソッドでは副作用を起こすべきではない、副作用を起こすのは早すぎる、とあります。 文章だとよくわかりませんが、以下のコンポーネントのライフサイクル図を見て何となくイメージができました。 なお、マウント(mounting)は最初にDOMが描画されるときです。 DOMが削除されるときをアンマウント(unmounting)と呼びます。

React lifecycle methods diagram

ここでの問題点は、最初のレンダリングと更新時で別のメソッドが呼び出されるため、2か所で同じメソッドを呼び出さなければいけないことです。

useEffect フックは componentDidMount と componentDidUpdate と componentWillUnmount がまとまったもので、renderの後に処理されます。 ReactはuseEffectに渡した関数を覚えていて、これを副作用と呼んでいます。 useEffectはコンポーネント内に記述するのでstateにアクセス可能です。 

 

クリーンアップを必要とする副作用

こちらについては、サンプルプログラムが単体では動作しないものだったので今回は割愛します。 クリーンアップを必要とする副作用は関数を返します。 サンプルプログラムはcleanup関数を返していましたが、別名でも名前なし(アロー関数)でも問題ありません。

何らかの外部のデータソースへの購読をする場合、マウント時にセットアップし、アンマウント時にメモリリークが発生しないようにクリーンアップが必要です。  (今回プログラムを作成して動かせませんでしたが、Java等でDB接続するときのオープン、クローズをイメージしてます。) クラスを使用する場合は、componentDidMountでデータ購読、componentWillunmountでクリーンアップします。 フックを使用する場合は、useEffectで購読とクリーンアップを一緒に書けます。 useEffectを実行後、Reactはクリーンアップのタイミングが来たら、実行します。 useeffectは1回だけでなく毎回レンダー時に実行されるため、次の副作用を実行する前にもクリーンアップします。

参考資料

副作用フックの利用法 – React

JavaScript初心者でもすぐわかる!DOMとは何か?

React コンポーネントのライフサイクルとメソッドの役割について - Qiita

React Hooks 入門してみた

React Hooksの知識が必要となりましたので、Reactのドキュメントを参考にサンプルプログラムを作成しました。

React Hooksとは

React 16.8で追加された機能で、props、stateなどのReact機能をクラスコンポーネントを書かずに使えます。 つまり関数コンポーネントでReactの機能が使用できます。 Reactドキュメントのフックの導入にある通り、 いわゆるuseStateという関数が最初のフック(Hook)になります。

フックを試してみる。

ドキュメントをもとにサンプルプログラムを作成しました。 create-react-appコマンドを実行後、App.jsを以下の通り作成しました。

import React,{ useState } from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const [count, setCount] = useState(0);

  return (
    <div className="App">
      <header className="App-header">
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
          Click me
        </button>
      </header>
    </div>
  );
}

export default App;

ボタンをクリックするとカウントされる画面が表示されました。 f:id:tosyan_samoarinan:20191201191913p:plain

以下はReact公式ドキュメントの引用です。

関数コンポーネントの中でローカルなstateを使うために呼び出しています。 このstateは以降の再レンダーの間もReactによって保持されます。 useStateは現在のstateの値と、それを更新するための関数とをペアで返します。 この関数はイベントハンドラーやその他の場所から呼び出すことができます。 クラスコンポーネントにおけるthis.setStateと似ていますが、新しいstateが古いものとマージされないという違いがあります。 フック早わかり – React

useStateの唯一の引数はstateの初期値です。 フック早わかり – React

複数のフックを使用する。

クラスコンポーネントの場合はthis.state、関数コンポーネントはuseStateを使います。 useState(0)の場合、stateの値は0になり、setCount関数はstateを更新するために使用します。 また1つのコンポーネント内で2回以上のフックを使用することが可能です。

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

function App() {
  const [count, setCount] = useState(0);
  const [second_count, setSecondCount] = useState(0);
  const [second_text, setCountText] = useState({text:"Help! Push Second Button"});

  const onclickFunction = () => {
    setSecondCount(second_count + 1);
    setCountText({text:"Thank you for putting button!!!!"})
  }

  return (
  <div className="App">
      <header className="App-header">
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
          Click me
        </button>
        <p>
          {second_text.text}.
          Yout clicked {second_count} times
        </p>
        <button onClick={onclickFunction}>
          Click me.Second button
        </button>
      </header>
    </div>
  );
}

export default App;

f:id:tosyan_samoarinan:20191201194707p:plain f:id:tosyan_samoarinan:20191201194805p:plain

参考資料

フックの導入 – React

フック API リファレンス – React

Amazon Transcribeを利用した日本語音声の文字起こしを試してみた

今回は以下の記事を参考に、Amazon Transcribeを使用した日本語音声の文字起こしを試してみました。 dev.classmethod.jp

Amazon Transcribeとは

音声をテキストに変換する機能。ディープラーニングが使用されており、 Amazon Transcribe APIを使用するとS3に保存された音声ファイルを文字起こしできます。 ライブ音源をリアルタイムで文字起こし可能とのこと。ただし、記事を読む限り現時点で日本語のリアルタイムでの文字起こしはできない模様。

公式では以下の利用用途が記載されています。

  • カスタマーサポートへの通話の文字起こし
  • 音声/動画コンテンツの字幕作成

Amazon Pollyとは

こちらはテキストを音声に変換する機能。ディープラーニングが使用されています。 今回初めて試してみましたが、自然な音声でびっくりしました。

試してみた

Pollyで音声ファイル(mp3)を作成

AWSコンソールからPollyの管理画面を開きます。 下記のような画面になるので、プレーンテキストに好きな文章を入力します。 f:id:tosyan_samoarinan:20191124232251p:plain

「音声を聴く」ボタンを押すと試聴ができます。 問題なければ「ダウンロード MP3」ボタンをクリックし、ファイルをダウンロード。

S3でバケットを作成

AWSコンソールからS3管理画面を開き、適当な名前でバケットを作成し、 さきほどPollyで作成した音声ファイルをアップロードします。

Amazon Transcribeで音声ファイルから文字起こし

AWSコンソールからTranscribe管理画面を開き、「Create job」ボタンを押します。 各項目は以下のように入力。他はデフォルトです。

  • Name TEST-Transcribe
  • Language Japanese(Japan)
  • Input file location S3 作成したバケットのパス
  • Format mp3

statusがin progressからCompleteに変わったら完成です。 f:id:tosyan_samoarinan:20191124233934p:plain

結果

読み込ませる用の⇒読み込ませるような になっていましたが、それ以外は問題なくできていました! f:id:tosyan_samoarinan:20191124234238p:plain

Transcribeがトラックライブという読みなのか・・というのはありますが、単語にカーソルを当てると音声の何秒あたりでその単語を発言したかわかるので、 音声を聴きなおすことも容易になるかと思います。 f:id:tosyan_samoarinan:20191124234658p:plain

まとめ

今回はTranscribeが日本語に対応したということで、Pollyと組み合わせて試してみました。 思ったよりも簡単に使用できたので、何かで使えないかな・・。直近では議事録作成くらいでしょうか。

参考サイト

音声から文字起こし、AWSのAIサービス「Amazon Transcribe」が日本語に対応 | 日経 xTECH(クロステック)

Amazon Polly(深層学習を使用したテキスト読み上げサービス)| AWS

Amazon Transcribe(音声をテキストに変換する機能を簡単に追加)| AWS

[Amazon Transcribe] 日本語対応したので、Pollyの音声を文字起こししてみました。 | Developers.IO

TypeScript,React,Amplify,AppSyncでの掲示板アプリについて

今回はTypeScript編です。参考にした記事はこちら。

qiita.com

Reactアプリのひな型作成

$ create-react-app boardapp_type --typescript  
$ cd boardapp_type  
$ amplify init  

create-react-appで簡単にReactアプリが作成可能。 なおgitリポジトリ(.gitフォルダ)も作成されていました。 一緒に作成されるtsconfig.jsonが存在するディレクトリは、TypeScriptプロジェクトのルートディレクトリを示しており、コンパイルオプションが記載されています。

tsconfig.json · TypeScript

GraphQLを追加

$ amplify add api

AWSにAppSyncのAPIがデプロイされる。

$ amplify push

ここで、AWSコンソールでAppSyncのAPIを確認すると、APIがデプロイされています。 APIのQueriesを使用することで、query,mutaitonのテストを実施。 f:id:tosyan_samoarinan:20191116234216p:plain f:id:tosyan_samoarinan:20191116234101p:plain

yarnでパッケージ登録

$ yarn add asws-amplify aws-amplify-react

gitで差分を確認するとpackage.jsonaws-amplify,aws-amplify-reactが追加されている。 amplify initしただけでは登録されない模様。 あとはyarn.lockも色々更新されている。

アプリケーション更新

こちらは記載されていたソースをコピー。

結果

無事動作しました。リアルタイム更新できることも確認できました。 f:id:tosyan_samoarinan:20191116233536p:plain Amplifyの使用については、少し慣れてきた気がしますが、React、TypeScriptの書き方が全然分かってないので、次はそちらの勉強が必要と感じました。

React,Amplify,AppSyncでの掲示板アプリについて

以下の記事を参考にアプリを作成してみました。 qiita.com

結果

f:id:tosyan_samoarinan:20191104230328p:plain

うまく行きました。 ただし、うまく表示させるには、コメント欄を参考に書き方を変える必要があります。 以下は作成した際に分からなかったところのまとめです。

create-react-appについて

ビルドツールの知識が不要でReactアプリを素早く作成するコマンドラインツール。 内部ではBabelとwebpack等を利用していますが、その知識は必要ありません。 Babelはコンパイラで古いバージョンに変換するときに使用するもので、 webpackは複数のモジュールを1つにまとめたファイルを出力するツールです。

Facebook公式のcreate-react-appコマンドを使ってReact.jsアプリを爆速で作成する - Qiita

Create React App · Set up a modern web app by running one command.

新しい React アプリを作る – React

【5分でなんとなく理解!】Webpack入門 - Qiita

【5分でなんとなく理解!】Babel入門 - Qiita

Yarnについて

Yarnはnode.jsのパッケージマネージャーです。

npmもnode.jsのパッケージマネージャーで互換性もありますが、インストールが速いようです。

Yarn

yarnとは - Qiita

Amplifyについて

AmplifyはAWSの各種サービスを使ったアプリ作成を容易にするJavaScriptフレームワーク、 および、開発者用サービスで構成されています。

amplify apiはHTTPリクエストでRESTあるいはGraphQLのエンドポイントとの通信を提供します。

graphQLはAWS AppSync(その他のサービスも可),RESTはAmazon API Gatewayを使用します。

今回はAppSyncを使用するので、graphQLを選択しています。

API

AppSync,GraphQLについて

AppSyncはGraphQLをベースとしたアプリケーションのバックエンドを提供するAWSのフルマネージドサービスです。

GraphQLはWeb APIの規格の一つ。Restful Web API(REST)の持つ問題を解決するために開発された規格。Facebookが開発しています。

クエリ言語とスキーマ言語で構成されています。

  • クエリ言語・・GraphQLのAPIをリクエストするための言語。
    • データ取得 query
    • データ更新 mutation
    • サーバサイドからのイベント通知 subscription
  • スキーマ言語・・GraphQLのAPIの仕様を記述するための言語

リクエストされたクエリはスキーマ言語で記述したスキーマに従ってGraphQL処理系により実行されてレスポンス生成されます。

【速報】マネージドGraphQLサービス「AWS AppSync」が一般公開(GA)されました! | Developers.IO

Web API初心者と学ぶGraphQL - Qiita

「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ - エンジニアHub|若手Webエンジニアのキャリアを考える!

AWS AppSyncで始めるGraphQL - Qiita

最後に

確認しながらだったので、15分では終わりませんでしたが、 掲示板アプリを作ることができました。

調べた結果として用語をまとめましたが、作成してから時間がたってしまったので、 以下を参考に、今度はTypeScriptでやってみたいです。

React+Amplify+AppSync+TypeScriptでリアルタイム掲示板アプリを作る - Qiita

AWS Amplifyを試してみた

はじめに

ブログの内容に一貫性がないですが、今回はAWS Amplifyを試してみたのでメモ。

参考にしたサイト

Amplifyについて

AmplifyはAWSの各種サービスを使ったアプリ作成を容易にするJavaScriptフレームワーク、 および、開発者用サービスで構成されています。

結果

f:id:tosyan_samoarinan:20191002201636p:plain s3にデプロイされて、URLからウェブページが表示されることまで確認。

感想

最初はフレームワークだけだと思っていたのですが、 デプロイまでやってくれるとは思いませんでした。 プログラミングに関しては、Amplifyを使用しないでアプリを作成したことがないですが、 今回実装しなかったCognitoやAPI Gatewayも楽になるようです。

次は以下をやってみたいですが、まずはJavaScript入門をしつつ、 これまでやったことの理解に努めたいと思います。 qiita.com

やっぱりJavaScriptの勉強が必要

はじめに

前回、TypeScriptのQuick StartでVue.jsをやってみましたが、 そもそもJavaScriptの構文を知らないので、ちんぷんかんぷんでした。

そこで以下の記事を見つけました。 mizchi.hatenablog.com

まさに「JavaScriptを詳しく知らない」ので、ES 2015 for Beginners編を確認。

  • ES2015、ES2016、ES2017・・と毎年更新される言語使用。ES2015は大規模な機能追加が行われたバージョン。
  • 新しく学ぶ人はES2015の仕様を追えばオッケー。古い情報は目を通さない方がよい。
  • ただ、IEをサポートするにはES2015で書いたコードをES5に変換して配布するのが主流。

もろもろ経緯があるものの、ひとまずES2015の仕様を抑えるのが重要ということを理解。

現在は記事で紹介されていた以下の書籍で勉強を開始しました。 jsprimer.net

まだ第1部のコメントまで。