Reactで動的に属性の値を生成する方法

HTML要素の属性の値を動的に生成するケースは往々にしてあるかと思います。
例えば、aタグのhref属性の値を動的に生成する等。

結果

JSXの記法でいけます。

<a href={'/item/' + this.props.id}>{this.props.name}</a>

このように、{...}の中に文字列もしくは式を値として入れることが出来るようです。
こんなスマートな記法あったのですね。知りませんでした。

MyBatisでorg.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

Spring Boot + MyBatisを使っていると、掲題の例外が発生することがよくあります。(私だけ?)
発生した時の対策をちょっとまとめてみたいと思います。

対策

  • MyBatisの設定クラス(@Configuration)に@MapperScanがついているか
  • @MapperScanに設定したパッケージ名は正しいか
  • Mapperクラスに@Mapperがついているか
  • XMLファイルが配置されているディレクトリ(もしくはパッケージ)は正しいか
    • たとえば、「xxx/yyy/zzz」なんてディレクトリにXMLファイルを配置したつもりが、「xxx.yyy.zzz」に配置したとか。

自分の場合、一番最後のやつによく当たります。

IntellJでパッケージ作っているのですが、操作ミスったりしてるのか、「xxx.yyy.zzz」なんてディレクトリになっちゃってます。
Finderでディレクトリ構成を確認して気付くというパターン。

Reactでシンプルな入力フォーム

Reactアプリケーションでシンプルな入力フォームを作るには?
シンプルな入力フォームとして、textbox, buttonを配置してみる。

結果

Reactでシンプルな入力フォームを作成出来た。
また、textboxに入力した値を表示させる方法について理解した。
Reactの1つの特徴を垣間見た気がしました。

シンプルな入力フォームのコード

render()でtextbox, buttonを定義する。

textbox

textboxは、値が変更された時(すなわち入力した時)に発火されるchangeイベントにupdateというイベントハンドラを設定する。
また、valueには、this.stateにあるvalueを設定する。

これにより、textboxに何がしか入力した時に、update関数が呼ばれ、this.state.valueが更新される。
stateが更新されることで、render()が呼ばれ再描画が実行される。

button

特筆すべきことは無いので省略。

import React, {Component} from 'react'

export default class SimpleForm extends Component {
  constructor (props) {
    super(props)
    this.state = {value: ''}
  }

  update (e) {
    this.setState({value: e.target.value})
  }

  submit (e) {
    window.alert('Inputted value: ' + this.state.value)
    e.preventDefault()
  }

  render () {
    return (
      <form onSubmit={e => this.submit(e)}>
        <input type='text' value={this.state.value} onChange={e => this.update(e)} />
        <input type='submit' value='send' />
      </form>
    )
  }
}

Reactでイベントの伝播

Reactアプリケーションで、コンポーネントのイベント伝播をしたい場合、どうすればいいのか。
ここでは、子コンポーネントから親コンポーネントにイベントを伝播することを想定している。

結果

コンポーネントthis.propにコールバック関数を定義し、その関数から親コンポーネントの呼び出すことが出来ました。 コールバックという仕組みは便利ですね。

コンポーネントのコード

this.propsonEventCallbackというコールバック関数を定義しています。
このコールバック関数は親のほうで使います。

import React, {Component} from 'react'

class Child extends Component {

  click (e) {
    this.props.onEventCallback({
      name: 'Child',
      type: 'click'
    })
  }

  render () {
    return (
      <div>
        <button onClick={e => this.click(e)}>click</button>
      </div>
      )
  }

}

export default Child

コンポーネントのコード

コンポーネントで定義したコールバック関数を属性としてJSXに入れます。
<Child onEventCallback={e => this.receive(e)} />コンポーネントでイベントが発生した時、onEventCallbackが呼ばれ、 更にreceive(data)が呼ばれます。

import React, {Component} from 'react'
import Child from './Child.js'

class Parent extends Component {
  receive (data) {
    alert(data.name + ' :: ' + data.type)
  }

  render () {
    return (
      <div>
        <Child onEventCallback={e => this.receive(e)} />
      </div>
    )
  }
}

export default Parent

ReactでHello World

Reactアプリケーションの環境構築、開発をサクっと行いたい場合は、どのような方法があるのだろうか。

結果

Facebookが提供するcreate-react-appを利用することで、手軽にReactアプリケーションの環境構築を行なえることが出来るようになります。
今までは所定のフォルダを作って、このファイルを配置して…、という手順を踏んでたり、このモジュールの依存関係はホニャララで悩ましい思いをしたと思いますが、create-react-appを利用することでサクっと出来るようになったのは嬉しいですね。

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

npmから入れます。グローバルインストールにします。

npm install -g create-react-app

create-react-appの使い方

Reactアプリケーションを作成するためには以下コマンドを実行するだけです。

➜  tmp create-react-app helloworld

うまく行くとターミナルに以下が出力されます。

Creating a new React app in /Users/xxx/tmp/helloworld.
...
omitted
...

Success! Created helloworld at /Users/xxx/tmp/helloworld
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd helloworld
  npm start

Happy hacking!

Reactアプリケーションの起動

先に作成されたReactアプリケーションのディレクトリに移動し、npm startを実行します。

  cd helloworld
  npm start

テンプレートリテラルというヤツ

こんなことが出来るようになるんやで〜。

const name = 'Hoge'
// Template Literal
alert(`Hello! ${name}!`) // Hello! Hoge!

alert(`3 + 5 = ${3 + 5}`); // 3 + 5 = 8

バッククォートで囲んで、${...}を入れると。これポイントな。

Dockerをためしてみるの巻

MacでDocker試したいのです。Oracleを入れて動作確認出来ればと思ってます。

結果

  • MacにDocker入れてOracle動かすことが出来た
  • Dockerイメージのダウンロードに時間がかかったぐらいで、特に難しいところはなし
  • SQLDeveloperからOracle on Dockerに接続出来る
  • 複雑なインストール必要ないのはメリット
  • Docker終了すると作成した表とかが失われるはず(?)なので、情報の保持の仕方については検討する必要あり
  • 直接インストールするのと比べて何が出来なくなっているか、どのような制約があるのかは分かってない

Docker for Mac

情報元

インストール手順

  1. Stable Channelをダウンロード
  2. https://docs.docker.com/docker-for-mac/install/#what-to-know-before-you-install
  3. Docker.dmgを実行
  4. ApplicationフォルダにDocker.appをコピー
  5. Docker.appをダブルクリック
  6. Docker実行
  7. ターミナルで以下確認
➜  ~ docker version 
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Tue Mar 28 00:40:02 2017
 OS/Arch:      darwin/amd64
Server:
 Version:      17.03.1-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:00:50 2017
 OS/Arch:      linux/amd64
 Experimental: true
  • ついでにもう少し確認してみる。
➜  ~ docker --version
Docker version 17.03.1-ce, build c6d412e
➜  ~ docker-compose --version
docker-compose version 1.11.2, build dfed245
➜  ~ docker-machine --version
docker-machine version 0.10.0, build 76ed2a6
  • docker runしてみる
➜  ~ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete 
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs 
the  executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, 
which sent it to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/

最初はhello-worldのイメージが見つからない。 その後、searchが実行され、Hitした場合はダウンロードされている。

Oracle11g on Docker for Mac

  • Dockerイメージの取得
➜  ~ docker pull wnameless/oracle-xe-11g
Using default tag: latest
latest: Pulling from wnameless/oracle-xe-11g
8aec416115fd: Pull complete 
695f074e24e3: Pull complete 
946d6c48c2a7: Pull complete 
bc7277e579f0: Pull complete 
2508cbcde94b: Pull complete 
0f39b2269587: Pull complete 
72a6f16c5b79: Pull complete 
Digest: sha256:e19b086b2d96325a4473d1a9cf44b9d8273b259c34b86d54e5c92452ac97ba54
Status: Downloaded newer image for wnameless/oracle-xe-11g:latest

えらい時間かかったが出来た。

  • Dockerイメージの確認
➜  ~ docker images
REPOSITORY                TAG                 IMAGE ID            CREATED             SIZE
wnameless/oracle-xe-11g   latest              51fad6f11394        3 months ago        2.24 GB
hello-world               latest              48b5124b2768        4 months ago        1.84 kB

Oracleで約2GB!?

➜  ~ docker run -d -p 49160:22 -p 49161:1521 -e ORACLE_ALLOW_REMOTE=true wnameless/oracle-xe-11g
9d1fb7238ab2125d307d7cf504077d371864a022c68a6664d7a97114e916e56e
  • SQLDeveloperからの接続

以下Readmeに接続情報とか記載されています。

github.com