Riot.js Redux Rails 4 / 8 「3で作成したformを、title-formタグとして独立させる」
はじめに
フロントにRiot.jsとReduxを使いサーバーサイドにRailsを使い、初めに環境構築し、次にReduxの使い方の流れをみて、最終的に簡単なTodoAppを作成する。
環境構築
- Riot.js Redux Rails 1 「環境構築」
簡単な例でReduxの流れをみる
- Riot.js Redux Rails 1 / 8 「環境構築」
簡単な例でReduxの流れをみる
- Riot.js Redux Rails 2 / 8 「Reduxを使ってtitleを表示させる」
- Riot.js Redux Rails 3 / 8 「formを追加しtitleの変更を可能にする」
- Riot.js Redux Rails 4 / 8 「3で作成したformを、title-formタグとして独立させる」
Todo Appの作成
- Riot.js Redux Rails 5 / 8 「Todoリストを表示する」
- Riot.js Redux Rails 6 / 8 「新たなTodoを追加出来るようにする」
- Riot.js Redux Rails 7 / 8 「完了したTodoをチェック出来るようにする」
- Riot.js Redux Rails 8 / 8 「チェックしてあるタスクを削除出来るようにする」
最終的に完成した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アプリの作成。