kdnakt blog

hello there.

React Nativeで「しがない問題」の話とか

この記事の続きです。

 

kdnakt.hatenablog.com

 

[普通に実装してみる] 

まずは、何はともあれreact-native init (プロジェクト名)で開始。

React Nativeはまだあまり触っていなくてスラスラと各オブジェクトの役割とかを意識して実装できないので、少し前に作りかけで放置している天気予報アプリを参考に、実装していく。

 

とはいえ、同じロジックを実装するのもめんどくさかったので、shiganai-problem/js/src/index.jsをコピペしてShiganaiService.jsにファイル名を変更し、Screen.jsから呼び出せるように、exportを追加する。

 

次に、WeatherScreen.jsを参考にShiganaiScreen.jsを実装する。ShiganaiServiceから取得した試行結果を画面ど真ん中に出力するだけ。

無事表示できた。 

f:id:kidani_a:20180115042052p:plain

なんと一発で当たりが出た。

 

[おまけ機能を実装してみる]

毎回毎回Command+Rでリロードして結果を表示するのは味気ないので、リトライボタンを置くことにする。 

下記のButtonコンポーネントを配置 

facebook.github.io

画面をリロードするために多少リファクタする。初期描画時にのみ取得していた文字列をstateで管理するように変更し、ButtonにonPressイベントをバインドしてクリックして見たところ、Buttonコンポーネントが動かない問題が発生。

f:id:kidani_a:20180115042702p:plain

 

シミュレータの真っ赤なエラー画面はいつ見ても心臓に悪い……。

とりあえず、シミュレータが表示しているエラーメッセージでググってみるとそれらしきStack Overflowを発見。

 

stackoverflow.com

onPress={this.retryShiganai}

となっていた箇所を

onPress={() => this.retryShiganai()}

に変更したら動いた。

 

f:id:kidani_a:20180115042150p:plain

これでリロードせずに何度でも試せる……と思ったら、renderメソッドの中でアロー関数を使うと、描画のたびに新しい関数を作ることになるためパフォーマンスに影響があるとの記載が。

仕方がないので、先ほどの部分を修正し、

onPress={this.retryShiganai}

コンストラクタに次の修正を加える。

this.retryShiganai = this.retryShiganai.bind(this);

動作に影響はない。何度でもリロードできた。 

 

機能差分ができたのが気になったので、JavaScriptバージョンにも同じようにリトライボタンを実装した。

 

[UIを変えてみる] 

さて、リロードの機能は実装されたものの、ボタンのはずなのにあまりにもボタンぽくないUIが不満だったので、違うライブラリを利用することにする。

 

github.com

https://raw.githubusercontent.com/wiki/APSL/react-native-button/button.png

サンプルで表示されていた画像が良さそうだったので、コレを使うことに。

 

ボタンの背景色を設定し、幅を調整して、センタリングして、結果テキストに改行を追加してそこそこいい感じになった。

f:id:kidani_a:20180117033457p:plain

課題として、結果テキストの長さによって、ボタンの表示位置が変わってしまうため、同じ場所をタップし続けてリトライする、ということができない。

暇を見つけたら、この点についても解消したい。

 

[まとめ] 

実装物はこちら。

github.com

 

そろそろWEB+DB PRESS 102の天気予報アプリ完成させなくては……。