読者です 読者をやめる 読者になる 読者になる

ushumpei’s blog

生活で気になったことを随時調べて書いていきます。

Reactコンポーネントをディレクトリにまとめる(ES6)

Reactのディレクトリ構成が全然わかりません。

Reactコンポーネントを分割する方法についてもメモです。ES6の文法の話だと思うのですが、正式なドキュメントが見つけられていないので間違いがあったら申し訳ないです。

書いたものをgithubに上げています。参考になれば幸いです。

webpackを使ってビルドを行なっており、設定ファイルは以下のようになっています;

  ...
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        query: {
          presets: ['es2015', 'stage-2', 'react']
        }
      }
    ]
  }

ディレクトリによる分割

例として以下のようにディレクトリを構成してみました。

src/
├── App
│   ├── App.js
│   ├── Bar.js
│   ├── Baz.js
│   ├── Foo.js
│   └── index.js
└── index.js

index.js内でimport App from './App'のようにモジュールとしてディレクトリを指定すると、ファイル./App/index.jsの内容がコンポーネントとして読み込まれます。./App/index.jsディレクトリ内のコンポーネントを組み立てておけば、呼び出し側はあたかも一つのコンポーネントのように扱うことができます。

ディレクトリでまとめることで、意味を保ったままコンポーネントの分割が行えそうです。「components」ディレクトリ以下にコンポーネントが大量に平置きされてしまうのを防げました。

感想

一方でコンポーネントの再利用性が下がる気もします。
一部のコンポーネントは他の箇所から再利用、他はディレクトリ内のコンポーネントを利用などしてしまうと、参照がわけわからなくなってしまいます。相変わらずディレクトリ構成は悩みどころです。
ちゃんと部品単位でのコンポーネント化を意識すると多少は回避できるかもしれません。

Railsからキーがキャメルケースのjsonを返す(jbuilder)

 Reactでアプリを書いていて思ったことのメモです。

 大概jsのオブジェクトのプロパティはキャメルケース(camel case)ですよね。
 Railsをサーバサイドにしたのですが、返却されるjsonがスネークケース(snake case)でした。

 クライアントサイドで書き換えるのも面倒だと思ったので、調べてみたところRails側で対応するのが楽なようです。

内容

 Rails(4から?)はjsonをリクエストした際に返却するオブジェクトの定義を、jbuilderというテンプレートエンジンで行うようです。

生成されている(例: _model.json.jbuilder)ファイルの先頭に

json.key_format! camelize: :lower
...

と記述するとキャメルケースに変更できました。

感想

 ちゃんとしたapiを作るならkey_formatも引数で指定できたほうがいいのだろうか?と思いましたが使う気がしないので何もしませんでした。
 クライアントからサーバへの送信の際にも書き換えが必要になると思いますが、どうしようかなーと考え中です。

 json.key_format!は単に文字列変換の関数を引数にとり、keyに適応する関数のようです。ここではcamelize: :lowerを渡していますが、他にも色々渡せますね。
 この関数はそんなに使い込む機会はないと思いますが、私は関数を引数に取る関数が結構好きです。だからどうしたという話ですが。

rubydoc: Jbuilder:key_format!

Promise + reduceで逐次処理

setIntervalでもいいですが、Promisereduceでもできるようです。

/* 逐次処理したいデータ */
const arr = [1,2,3,4,5];

arr.map( /* データの配列から`Promise`を返す関数の配列を作る */
  e => (
    () => new Promise(
      (res, _) => {
        setTimeout(
          () => {
            /* ここに処理を書く、ここではコンソールに出力 */
            console.log(e);
            res(e);
          },
          /* 処理の間隔 */
          1000
        );
      }
    )
  )
).reduce( /* reduceを使って、Promiseをthenでつなぐ */
  (p, c) => p.then(c),
  Promise.resolve() /* 初期値 */
)

一応のメリットは、処理を中断する際の記述がわかりやすくなることだと思います。

const arr = [1,2,3,4,5];

arr.map(
  e => (
    () => new Promise(
      (res, rej) => {
        setTimeout(
          () => {
            if(e == 4) return rej('4 is an unlucky number');
            console.log(e);
            res(e);
          },
          1000
        );
      }
    )
  )
).reduce(
  (p, c) => p.then(c),
  Promise.resolve()
).catch(
  e => console.error('Error!!!: ' + e)
)

ちゃんとする場合はsetTimeoutのコールバック関数内にtry...catchで記述するのがいいでしょう。

setTimeout(
  () => {
    try {
      if(e == 4) throw new Error('4 is an unlucky number');
      console.log(e);
      res(e);
    } catch(e) {
      rej(e);
    }
  },
  1000
);

感想

なんとなくメソッドチェーンにしたがる性分なのかもしれません。

React Native実機動作中のcommand+d

お疲れ様です。

とりあえず結論というか、言いたい事です。

React Nativeで作ったアプリを開発段階で実機にXcodeで転送した場合、
シミュレータでcommand+dしたときに出るメニューは、実機を振ると出すことができるようです。
(2017/02/22時点)

説明

最近、とりあえずiOSアプリのデモ作ってみないか?という縁がありReact Nativeを触ったりしています。

React Nativeはreact-native run-iosとか打てばシミュレータが立ち上がるのですが、カメラを使う機能などシミュレータでできないことは、Xcode経由で実機に転送する必要があります。

シミュレータではLive Reloadという、コードを修正するたびに再読込してくれる機能を有効にできるのですが、実機ではコードを修正するたびにビルド → 転送みたいな事をしないといけないと思っていました。

というのもLive Reloadを有効にするためのメニューは、シミュレータではcommand+dで出るのですが、実機ではショートカット打てないためです。

しかし実機に入れた場合でも、立ち上げ時にはローカル経由でjavascriptを読み込みに行っているようだし(完全にReact Native勉強不足です)。どうにかならないかなーと思い色々いじってみると、実機を振ったらメニューが出ました。その他やってみたこと

  • 音量ボタン同時押し
  • 二本指で画面下をスワイプ
  • 三本指で画面下をスワイプ
  • 二本指で画面をピンチ
  • 三本指で画面をピンチ

だからどうしたという感じですね。

感想

結局実機を振るとメニューが出たのですが、振る動作を使ったアプリを作りたい場合はどうするのでしょうか?

それはそうと毎回場当たり対応で知識が集積していかない感が集積しています。

ブラウザでテキスト読み上げるコンポーネント: react-voice-components

テキスト読み上げをしてくれるReactコンポーネントの存在を知りました。grvcoelho/react-voice-components

ブラウザで音声を使って何かしたいと思っていたので、試しに触ってみて、GitHub Pageにあげてみました。 以下ちょっと苦労したので、メモです。

Reactを動かせる環境の作成

半年前くらいに作ったコンパイルの環境がかなり古くなっていたので、facebookincubator/create-react-appで作り直しました。インストールに少々時間がかかりましたが、とても便利ですね。

npmで入れたreact-voice-componentsが動かない?

npmで入れたreact-voice-componentsだと、create-react-appで作った環境との相性なのか、コンパイルされずブラウザエラーが発生して動きませんでした。webpackの設定ファイルを上書けばいいようですが、とりあえず、git submoduleリポジトリコンパイル対象のディレクトリにクローンして使用することにしました。せっかくなので、本当に問題があるのなら、いずれ修正を送ってみようかと思います。

書いたコードです;

ushumpei/play-with-react-voice-components

GitHubページを公開する

GitHubページの公開方法は3つあるようで、mastergh-pagesブランチのindex.htmlからか、master/docsを使うか、だそうです。

今回はdocsを作成して公開しました。静的リソース(cssjs)の指定が絶対パスだったため、読み込まれなくて困りました。

感想

  • テキストから音声ファイルとして吐き出すことはできるか気になりました。
  • Reactで綺麗に書けるようになりたいです。
  • GitHubはとても太っ腹です。
  • リポジトリの作者がすでにデモページを作成してくださっているようです。。。