2019年 1月 の投稿一覧

[Firebase] Authenticationでメール認証 (Web編) その1

Firebaseの機能を順次試していきたいと思います。
FirebaseではAuthenticationを利用することで様々な認証を用いることができます。今回実装するメールアドレスの他に各種SNSやSMSなどにも対応可能です。Webの他にiOSやAndroidなどにも導入可能。

今回は単純なログイン機能をWebページに実装してみます。
メールアドレスとパスワードを入力すると登録やログインできるようになります。

Authenticationでログイン

コンソール上の設定

Firebaseのコンソールにログインし、新しくプロジェクトを作成するか、既存のプロジェクトを選択します。

プロジェクトのダッシュボードに移動したら、早速Authenticationの設定を進めていきます。
まずは左側のメニューの「Authentication」をクリックし、右ペインが切り替わったら「ログイン方法」タブをクリック。

「メール/パスワード」の行をクリックし、「有効にする」のスライダーをクリック。
その後「保存」ボタンをクリック。

この後JSを書き始めるのですが、その前にプロジェクトの情報を取得します。プロジェクトのコンソール右上にある「ウェブ設定」ボタンをクリック。

JSの設定部分の雛形が表示されますので、これをコピーします。

これでブラウザでのFirebaseの必須の設定はひとまずこれで完了です。
簡単でしたねw

認証処理をJSで書く

今回は認証部部のUIがまるっとセットになったfirebaseui-webを使っていきます。

ここでは次の3つのファイルを作成しています。

config.js
前項でコピペしたコンソールの内容を保存します。
login.html
ログイン画面のHTML
done.html
ログイン完了画面のHTML

続きを読む

[Firebase] 静的なWebサイトをホスティングする

FirebaseのHostingを利用すれば基本無料で静的なサイトを運用できます。
独自ドメインも追加でき、何らならSSL証明書も無料でついてくるという太っ腹。もしサイトが成長し膨大なアクセスが発生した場合は課金する必要がありますが、こちらがプラン変更しない限り料金は一切発生しません。

ドメインやDNSの準備や設定、本番へデプロイ(反映)するにはコマンドを叩く必要がありますが、それさえ乗り越えてしまえばさほど難しくはありません。

環境の準備

プロジェクトの作成

サイトを設置するためのプロジェクトが必要になります。
プロジェクトの作成方法は以下のページを参照くださいませ。

Node.jsのインストール

Hostingの利用は原則としてTerminalなどのCLI上でコマンドを叩いて行いますので、まずはその準備を行います。

Node.jsがインストールされている必要があります。公式サイトからダウンロードしインストールしてください。「推奨版」と書かれている方でOKです。

もしmacOSを利用されている場合で、凝った設定をしたい場合は以下のページを参照くださいませ。

FirebaseのCLIツールをインストール

Node.jsをインストールするとnpmという、様々なライブラリやツールを取得できる便利なツールが同時に入るのですが、これを使ってインストールを行います。

$ npm install -g firebase-tools

今回は以下のバージョンが入りました。

$ firebase --version
6.3.0

続きを読む

[Firebase] プロジェクトを新規に作成する

しばらく見ないうちにFirebaseでできることが驚くほど増えていたので、今回からしばらくFirebaseを触ってみたいと思います。

Firebaseが何たるかは公式サイトをご覧ください。

プロジェクトを作成する

Firebaseのコンソールへログインします。Googleアカウントが必要になりますので、Firebaseで利用したいアカウントでログインを行ってください。

「プロジェクトを追加」ボタンをクリック

プロジェクトの情報を入力する画面になります。

続きを読む

はじめてのReact #22「ToDoアプリを作る」 後編

3回に渡ってお送りしたToDoアプリ開発も最終回。今回はAjaxを利用しデータをサーバに保存してみます。

Propsのデータ型をチェック

以前取り上げたPropsのデータ型のチェックを導入しておきます。

プロジェクトも運用段階に入りComponentがどこからどのように呼び出されるか、収集がつかなくなったとしても呼び出し方さえ守ってもらえれば何とかなったりするものです(それが良いかはさて置き)。また誤った利用方法をするとテスト段階でエラーを明示的に出してくれるのもありがたいものです。

src/header.js

import PropTypes from 'prop-types';

// <Header>
//   React ToDo
// </Header>
Header.propTypes = {
  children: PropTypes.string.isRequired
};

src/todocreate.js

import PropTypes from 'prop-types';

// <ToDoCreate onClick={this.handleClick} />
ToDoCreate.propTypes = {
  onClick: PropTypes.func.isRequired
};

src/todolist.js

import PropTypes from 'prop-types';

// <ToDoList data={this.state.todo} remove={this.handleRemove}/>
ToDoList.propTypes = {
  data: PropTypes.array.isRequired,
  remove: PropTypes.func.isRequired
};

src/todoitem.js

import PropTypes from 'prop-types';

// <ToDoItem key={i.id} item={i} remove={this.props.remove} />
ToDoItem.propTypes ={
  item: PropTypes.object.isRequired,
  remove: PropTypes.func.isRequired
};

データをサーバ側で管理する

APIサーバを用意

Reactから話がずれますが、学習用に保存や取り出しを行うAPIサーバをNode.jsで準備します。かなり簡易的な物なので本番投入はしないでください。しないとは思いますがw

まずは適当な名前のディレクトリを作成しカレントディレクトリを別の場所に移します。今のプロジェクトは全く別の場所に作成してください。その後簡単にHTTPサーバを作成できるexpressを入れます。

$ mkdir apiserve; cd apiserve
$ npm install express

詳細は説明しませんが、以下のスクリプトをexpressをインストールしたディレクトリに適当な名前で保存します。ここではserve.jsとしました。

続きを読む

はじめてのReact #21「ToDoアプリを作る」 中編

前回に引き続き今回もToDoアプリを作っていきます。目標としてはフォームの使い勝手を向上させつつToDoの削除に対応するところまでとなります。

フォームを改良する

Submitイベントに対応

現状、登録フォームのテキストボックスに内容を入力しエンターキーを押した瞬間、再読込されてしまいます。これを防ぐには、formタグにonSubmitイベントを定義してあげればOK。今回はエンターキーを押すと確認用のダイアログを表示し、OKボタンが押されれば追加処理を行う形に変更しました。

src/todocreate.jsを以下のように変更します。

import React, { Component } from 'react';

class ToDoCreate extends Component {
  constructor(props){
    super(props);
    this.state = {
      newtodo: ""
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(e){
    this.setState({
      newtodo: e.target.value
    });
  }

  handleSubmit(e){
    let newtodo = this.state.newtodo;
    if(newtodo !== "" && window.confirm('本当に登録しますか?')){
      this.props.onClick(newtodo);
      this.setState({newtodo:""});
    }
    e.preventDefault();
  }

  render(){
    return(
      <form onSubmit={this.handleSubmit}>
        <input type="text" value={this.state.newtodo} onChange={this.handleChange}/>
        <button>追加</button>
      </form>
    );
  }
}

export default ToDoCreate;

注意すべき点としてはconfirm()ではなく、window.confirm()とする必要があるところでしょうか。

Validationを行う

もう一つの問題点として、テキストボックスが空でも登録されている点ですね。これも直して置きます。src/todocreate.jsのhandleSubmit()を以下のように変更しました。空文字列または2文字未満であれば何もしません。

  handleSubmit(e){
    e.preventDefault();

    let newtodo = this.state.newtodo;
    if(newtodo === "" || newtodo.length < 2){
      return(false);
    }

    if(newtodo !== "" && window.confirm('本当に登録しますか?')){
      this.props.onClick(newtodo);
      this.setState({newtodo:""});
    }
  }

テキストボックスにfocusする

ToDoを入力する際にわざわざテキストボックスをクリックするのも面倒なので、ページが読み込まれたと同時にfocusをしてあげます。src/todocreate.jsを以下のように変更します。

import ReactDOM from 'react-dom';  //追加

class ToDoCreate extends Component {
  // (snip)

  componentDidMount(){
    ReactDOM.findDOMNode(this.refs.newtodo).focus();
  }

  // (snip)

  render(){
    return(
      <form onSubmit={this.handleSubmit}>
        <input type="text" ref="newtodo" value={this.state.newtodo} onChange={this.handleChange}/>
        <button>追加</button>
      </form>
    );
  }
}

上記は変更した部分だけを抜き出しています。

まずReactDOMの機能を利用しますので新たにimportしました。
componentDidMount()はLifeCycleの機能。ComponentがDOMツリーに追加された瞬間に呼び出されます。ここで単純にfocus()メソッドを実行してあげればよいのですが、問題はどうやってテキストボックスを特定するかです。

今回はテキストボックスに<input type="text" ref="newtodo">といった形でref属性を追加しました。この属性をつけておくとReactから簡単に参照することができるようになります。この場合だとthis.ref.newtodoですね。

ReactDOM.findDOMNode()は最終的にDOMオブジェクトを返却しますので、これでテキストボックスを検索し、戻り値のDOMオブジェクトに対してfocus()を実行しているといます。

Lifecycleについては過去の記事を参照してください。

続きを読む

はじめてのReact #20「ToDoアプリを作る」 前編

前回準備した環境を使って、早速Webアプリを作ってみたいと思います。こういうときはToDoアプリを作るのが伝統となっていますので、それに習いますw

なお、本来であればテストコードを書きながら進めるべきだとは思いますが、今回は割愛しております。

準備編

プロジェクトの作成

rtodoという名前でプロジェクトを新規作成しました。rはReactで作るぞという意思表示で特に意味はありませんw 好きな名称をつけてください。

$ create-react-app rtodo

Gitリポジトリの準備

GitHubにもrtodoという名前でリポジトリを準備しました。まずはこいつにgit pushします。
https://github.com/katsube/rtodo

$ git remote add origin git@github.com:katsube/rtodo.git
$ git push -u origin master

Componentを作ってみる

新しいComponentを作る

まずは腕鳴らしに簡単なComponentを用意してみます。src/header.jsというファイルを作成し、その中に以下のコードを記述します。render()でタグを描画しているだけですね。h1の中はprops.childrenでもらった文字列をそのまま出しています。

import React, { Component } from 'react';

class Header extends Component {
  render() {
    return(
      <header>
        <h1>{this.props.children}</h1>
      </header>
    );
  }
}

export default Header;

最後のexport文を忘れないように気をつけてください。これを記述することで他のファイルからこのComponentを利用することができるようになります。

子供の要素にアクセスする方法(this.props.children)については過去の記事を参照してください。

続きを読む

はじめてのReact #19「開発環境を準備する」create-react-app編

ここまでご紹介してきたサンプルは学習やちょっとした検証には使えるのですが、実際に本番環境で動かすのには向いていません。というわけで今回は本番環境で動かすコードを作成するための開発環境を準備してみたいと思います。

Reactの開発環境

Node.jsのインストール

まず最初にNode.jsを入れる必要があるのですが、アップデートに対応しやすくするためバージョン切り替えが手軽に行えるツールをインストールした上でNode.jsの最新版を入れます。

MacやLinuxならnodebrew

Windowsならnodist

今回は以下のバージョンで構築を開始します。npmはNodejs用のパッケージマネージャーで、これを使って様々な便利ライブラリやツールをインストールすることができます。

$ node --version
v11.7.0
$ npm --version
6.5.0

create-react-appのインストール

Reactの開発環境をゼロから作ろうとすると中々に面倒なのですが、コマンド一発で必要な物を一式揃えてくれる便利ツールがfacebookより公式に提供されているので今回はこちらを利用してみます。

では先ほどインストールしたnpmコマンドを利用してこのcreate-react-appを入れます。npmを利用するとコマンド一発で入ります。

$ npm install -g create-react-app

今回は以下のバージョンが入りました。

$ create-react-app --version
2.1.3

続きを読む

はじめてのReact #18「Ajaxでデータ取得」

昨今のWebアプリではWebAPI(RESTful API等)をAjaxなどで叩きデータを取得する、もしくはデータを保存するといった行為を日常的に行っているわけですが、今回はAjaxでデータ取得し表示するまでに挑戦してみます。

MonsterView Component

とあるRPGのモンスターの一覧が記録されたJSONファイルをAjaxで取得し、そのままReactで表示するサンプルです。公式ドキュメントの例をちょろっといじったものになります。

サンプル

データファイルです。実際にはサーバ側で動的に出力することが多いと思いますが、今回は静的なファイルで試します。ファイル名はdata.json

{
  "monsters": [
    { "id": 1, "name": "スライム", "hp": 10 },
    { "id": 2, "name": "ドラキー", "hp": 12 },
    { "id": 3, "name": "おおありくい", "hp": 36 }
  ] 
}

実際の処理を行うHTMLです。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>MonsterView</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>

<div id="root"></div>

<script type="text/babel">
class MonsterView extends React.Component {
  constructor(props) {
    super(props);
    this.state ={
      isLoaded: false,
      error: null,
      monsters: []
    }
  }

  componentDidMount() {
    fetch("https://s3-us-west-2.amazonaws.com/blog.katsubemakito.net/static/react1st/18/data.json")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            monsters: result.monsters
          });
        },
        (error) => {
          this.setState({
            isLoaded: true,
            error: error
          });
        }
      )
  }

  render() {
    if (this.state.error) {
      return <div>Error: {this.state.error.message}</div>;
    }
    else if ( !this.state.isLoaded ) {
      return <div>Loading...</div>;
    }
    else {
      return (
        <ul>
          {this.state.monsters.map( monster => (
            <li key={monster.id}>
              {monster.name} {monster.hp}
            </li>
          ))}
        </ul>
      );
    }
  }
}

ReactDOM.render(
  <MonsterView />,
  document.getElementById('root')
);
</script>
</body>
</html>

続きを読む

はじめてのReact #17「CSSを適用する」

これまで何の前触れもなくチラッと出てきたComponentにCSSを適用する方法について、いよいよ解説したいと思います。まぁブログの構成(順番)を間違えてるだけなんですけどねw もっと早く取り上げるべきだったw

ダイアログ Component

Component名は前回と同じですが、今回はボタンをクリックする度に文字色が変化するサンプルにしてみました。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Dialog</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

  <style type="text/css">
    .dialog {
      border: 1px solid gray;
      background-color: beige;
      text-align: center;
    }
  </style>
</head>
<body>

<div id="root"></div>

<script type="text/babel">
class Dialog extends React.Component {
  constructor(props) {
    super(props);
    this.state ={
      i: 0
    }
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(){
    this.setState({
      i: this.state.i + 1
    });
  }

  render() {
    let colormap = ["black", "red", "green", "blue"];
    let i = this.state.i % colormap.length;
    let color = {
      color: colormap[i]
    };

    return (
      <div className="dialog">
        <h1 style={color}>HelloWorld</h1>
        <button onClick={this.handleClick}>チェンジ</button>
      </div>
    );
  }
}

ReactDOM.render(
  <Dialog />,
  document.getElementById('root')
);
</script>
</body>
</html>

続きを読む

Redmineに投稿されたURLからREFERERを送信しない

OSSのプロジェクト管理ツールである「Redmine」を利用している方も多いと思いますが、デフォルトのままだと投稿されたURLをクリックするとRedmineサーバのFQDNが参照元(REFERER)として相手方サーバに渡されてしまいます。

以下はGoogle Analyticsで「参照サイト」の項目を表示したところですが、数は少ない物の社内RedmineのFQDNと思われるREFERERが渡ってきているのがわかります。

もちろんオープンなプロジェクトであれば問題ないでしょうし、何らかのアクセス制限がされていれば閲覧することはできないのですが、管理者からするとあまり気持ちの良い物ではありませんし、一時的に設定をミスして全公開状態になることも考えられます。

今回はそもそもREFERERを渡さない設定を行います。Redmineにプラグインを入れてちょちょいと設定するだけです。

続きを読む

はじめてのReact #16「Componentの連携」子要素にアクセスする

これまでは、最終的にrender()する際には<Foo />のようにタグで何らかの文字列や要素を囲わない状態でした。今回はそこから一歩進んで<Foo>Hello!</Foo>のように何らかの要素を挟んでみたいと思います。

ダイアログ Component

おもしろサンプルが思いつかなかったので、公式ドキュメントほぼそのまま、ダイアログの作成を行います。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>Dialog</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>

<div id="root"></div>

<script type="text/babel">
class Dialog extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div style={{backgroundColor:'lightpink', width:'500px', border:'5px solid red'}}>
        {this.props.children}
      </div>
    );
  }
}

ReactDOM.render(
  <Dialog>
    <h1>Hello! World</h1>
    nice to meet you!
  </Dialog>,
  document.getElementById('root')
);
</script>
</body>
</html>

続きを読む

はじめてのReact #15「Componentの連携」複数同時に処理をする

いよいよReactの真骨頂っぽいところに足を突っ込んでみます。前回はComponentの中にComponentが1つだけ内包されていましたが、これを複数にしてみたいと思います。

西暦・和暦 相互変換Component

今年の5月には新しい年号が爆誕するのにちなんで、西暦と和暦を相互に変換するComponentを作成してみたいと思います。今回も公式ドキュメントのサンプルを改変した物になります。

実行すると昭和、平成、西暦の3つのテキストボックスが表示されます。いずれか1つに入力すると残りの2つが連動して変化します。コードがちょっと長いのですが、理解のしやすさを優先しただけで実際にやってることは大したことありません。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>HeiseiConvert</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>

<div id="root"></div>

<script type="text/babel">
class YearInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.props.onYearChange(e.target.value);
  }

  render() {
    const year = this.props.year;
    const type = this.props.type;

    return (
      <fieldset>
        <legend>{type}:</legend>
        <input value={year}
               placeholder={this.props.placeholder}
               onChange={this.handleChange} /> 
               年
      </fieldset>
    );
  }
}

class HeiseiConvert extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
          ad: "",
       showa: "",
      heisei: ""
    };

    this.handleAdChange     = this.handleAdChange.bind(this);
    this.handleShowaChange  = this.handleShowaChange.bind(this);
    this.handleHeiseiChange = this.handleHeiseiChange.bind(this);
  }

  handleAdChange(year) {
    this.setState({
          ad: year,
       showa: this.toConvert(year, -1925),
      heisei: this.toConvert(year, -1989)
    });
  }

  handleShowaChange(year) {
    this.setState({
          ad: this.toConvert(year, 1925),
       showa: year,
      heisei: this.toConvert(year, -63)
    });
  }

  handleHeiseiChange(year) {
    this.setState({
          ad: this.toConvert(year, 1988),
       showa: this.toConvert(year, 63),
      heisei: year
    });
  }

  toConvert(year, value){
    if( Number.isNaN(parseFloat(year)) ){
      return('');
    }
    return( Number(year) + value);
  }

  render() {
    return (
      <div>
        <YearInput
          type="昭和"
          placeholder="例: 64"
          year={this.state.showa}
          onYearChange={this.handleShowaChange} />
        <YearInput
          type="平成"
          placeholder="例: 30"
          year={this.state.heisei}
          onYearChange={this.handleHeiseiChange} />
        <YearInput
          type="西暦"
          placeholder="例: 2019"
          year={this.state.ad}
          onYearChange={this.handleAdChange} />
      </div>
    );
  }
}

ReactDOM.render(
  <HeiseiConvert />,
  document.getElementById('root')
);
</script>
</body>
</html>

続きを読む

はじめてのReact #14「Componentの連携」入力された値を動的に渡す

今回はユーザーが入力した値を別のComponentにリアルタイムに渡すサンプルを作ってみたいと思います。

カラーチェッカーComponent

テキストボックスに色の名前を入力すると、ほぼリアルタイムに■の色が変化するComponentになります。Reactの公式ドキュメントの水の温度によって表示を変化させるサンプルを改変した物です。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>ColorChecker</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>

<div id="root"></div>

<script type="text/babel">
function ShowColor(props) {
  return(
    <p style={{color:props.color, fontSize:'20px'}}>■</p>
  );
}

class ColorChecker extends React.Component {
  constructor(props) {
    super(props);
    this.state = {color: ''};

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({color: e.target.value});
  }

  render() {
    const color = this.state.color;
    return (
      <fieldset>
        <legend>色名を入力してください:</legend>
        <input
          value={color}
          onChange={this.handleChange}
          placeholder="例:Red" />

        <ShowColor color={color} />
      </fieldset>
    );
  }
}

ReactDOM.render(
  <ColorChecker />,
  document.getElementById('root')
);
</script>
</body>
</html>

続きを読む

はじめてのReact #13「フォームと連動する」ラジオボタン編

Reactでフォームを使ってみようシリーズも佳境に差し迫った第4弾。今回はラジオボタンを触ってみます。

時限爆弾の解体ラジオボタンComponent

もはら映画で定番となった、時限爆弾の解体シーンで「青と赤どちらのコードを切るか…」を再現するComponentを作ってみたいと思います。3色のラジオボタンが並んでおりハズレを選択(コードを切断)すると爆発します。

サンプル

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>BomButton</title>
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

  <!-- Don't use this in production: -->
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>

<h1>BomButton</h1>
<p>線を一つ選んで爆弾を解除してください</p>
<img src="./bom1.png">
<div id="root"></div>

<script type="text/babel">
class BomButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      radio: [
        {cd:'red',   name:"赤", checked:false},
        {cd:'blue',  name:"青", checked:false},
        {cd:'green', name:"緑", checked:false}
      ],
      lastclick: null  //最後に選択された色を入れる
    };

    // State内の色の中から抽選を行う
    let i = Math.floor(Math.random() * 100) % this.state.radio.length;
    this.hit = this.state.radio[i].cd;

    // 爆発時の素材を事前ロードしておく
    this._preload();

    // イベント用メソッド
    this.handleRadioClick = this.handleRadioClick.bind(this);
  }

  /**
   * 爆発時の素材を事前ロード
   */
  _preload(){
    this.se = new Audio('./bomb1.mp3');
    this.se.load();

    let img = new Image();
    img.src = "./bakuhatsu.png";
  }

  /**
   * ラジオボタンをクリック
   */
  handleRadioClick(e) {
    if( ! confirm('本当にこの線で良いですか?') ){
      return(false);
    }

    let name  = e.target.name;
    let value = this.state.radio.map( (item)=>{
      return({
        cd: item.cd,
        name: item.name,
        checked: (item.cd===name)? true:false
      })
    });

    this.setState({
        radio: value
      , lastclick: name
    });
  }

  render() {
    //----------------
    // 当選したら爆発
    //----------------
    if( this.hit === this.state.lastclick ){
      this.se.play();
      return <div><img src="./bakuhatsu.png" /></div>
    }
    //----------------
    // 選択肢の表示
    //----------------
    else{
      const radio = this.state.radio;
      const listItems = radio.map((r) =>
        <label key={r.cd.toString()} style={{color: r.cd}}>
          <input
            type="radio"
            name={r.cd}
            value={r.cd}
            checked={r.checked}
            onChange={this.handleRadioClick} />
          {r.name}<br />
        </label>
      );
      return <form>{listItems}</form>
    }
  }
}

ReactDOM.render(
  <BomButton />,
  document.getElementById('root')
);
</script>
</body>
</html>

続きを読む

[VisualStudio Code] 言語によってインデント幅を変更する

昔からの習性でコーディングする際のインデントはタブ派なんですよ、スペースの数は4つ。
ところが…

  • GitHubでソース見るとタブがスペース8つ分になる
    • ブラウザのデフォルト動作
    • URLの最後に?ts=4とかつけると変更はできるが…
  • JavaScript界隈だとスペース2個が主流っぽい

という空気を感じてまして、長いものには巻かれろ精神で、ひとまずJSだけインデントをスペース2個に変更することにしました。

続きを読む