Learn プログ

-マナビメモ-

Riot.js Redux Rails 4 / 8 「3で作成したformを、title-formタグとして独立させる」

はじめに

フロントにRiot.jsとReduxを使いサーバーサイドにRailsを使い、初めに環境構築し、次にReduxの使い方の流れをみて、最終的に簡単なTodoAppを作成する。

環境構築

簡単な例でReduxの流れをみる

簡単な例でReduxの流れをみる

Todo Appの作成

最終的に完成したTodo App
https://github.com/atfeo/Riot_Redux_Rails

参考

3で作成したformを、title-formタグとして独立させる。

title-formタグの作成

formタグをsample-outputタグから独立させるためのtitle-formタグを作成する。 sample-outputタグからform以下をそのまま持ってくる。

<!-- ./client/src/tags/title-form.tag -->
<title-form>
  <form onsubmit={changeTitle}>
    <input type="text" name="newTitle">
    <input type="submit" value="Change Title">
  </form>

  <script>
    changeTitle() {
      if (!this.newTitle.value) {
        return;
      }
      this.opts.store.dispatch({ type: 'CHANGE_TITLE', data: this.newTitle.value })
      this.newTitle.value = ''
    }
  </script>
</title-form>

sample-outputタグはこのようになる。

<!-- ./client/tags/sample-output.tag -->
<sample-output>
  <h1>{this.opts.store.getState().title}</h1>
</sample-output>

index.jsの書き換え

title-formタグをマウントするためにindex.jsの必要な書き換え等を行う。

// ./client/src/index.js
// 追加
import './tags/title-form.tag';

// 書き換え
document.addEventListener('DOMContentLoaded', () => {
  riot.mount('*', { store: reduxStore });
});

これら以外はそのまま。

index.html.erbに追加

title-formタグの追加

# ./app/views/top/index.html.erb
<sample-output></sample-output>
<title-form></title-form>

ブラウザでlocalhost:5000を更新して確認。 表示は変わらない。 しかし、フォームに入力した文字がタイトルに反映されなくなっている。
Riotではonsubmitなどのイベントハンドラが呼ばれた後、this.update()が自動的に呼ばれるので、sample-outputタグ内にformタグがあった時は{this.opts.store.getState().title}が新しいtitleを取りに行っていた。しかし、独立したタグになったためsample-outputタグではthis.update()が呼ばれず変更が反映されない。(この理解であっているかわからない。)

更新が反映されるようにする

storeにはsubscribe()というメソッドがあり、これはdispatchでactionが送られるたびに呼ばれるらしいので(subscribeについてよく理解できていない。)、これを使う。

<!-- ./client/tags/sample-output.tag -->
<sample-output>
  <h1>{this.opts.store.getState().title}</h1>

  <script>
    this.opts.store.subscribe(() => this.update())
  </script>
</sample-output>

これでタイトルの更新が反映されるようになった。
ブラウザでlocalhost:5000を更新して確認。

リファクタリング

action

今後アクションが増えた時アクションがまとまっていた方が良いのでactions.jsにまとめる。

// ./client/src/actions.js
module.exports = {
  changeTitle,
};

function changeTitle(newTitle) {
  return { type: 'CHANGE_TITLE', data: newTitle };
}

actions.jsにアクションを切り出したのでアクションを使っていた部分を書き換える。

// ./client/src/tags/title-form.tag
<script>
  // 追加
  const actions = require('../actions.js')
  changeTitle() {
    if (!this.newTitle.value) {
      return;
    }
    // 書き換え
    this.opts.store.dispatch(actions.changeTitle(this.newTitle.value))
    this.newTitle.value = ''
  }
</script>

今までと変わらないことをブラウザでlocalhost:5000を更新して確認。

Reduxの使い方の大まかな流れがを確認。次回からはtodoアプリの作成。

Riot.js Redux Rails 5 / 8に続く