Reactを触った経験を元にRiotに手を出しています。
コンポーネント指向で開発したくても、AngularやReactはビルドツールが複雑な印象を持たれており、拒否反応がある社内の古参開発者には勧めにくいと感じていました。Riotはscriptタグベースで始められるので、コンポーネント指向入門としては敷居が低くその点が魅力的ですね!Riotで感覚を掴んでもらえれば「今度はReact試してみる???」という気運も高まってきそうです。
今日はRiotを使ったコンポーネント間のデータ連携を整理してみたいと思います。
データ渡しのパターン
ざっと調べた限りでは以下の4パターンがあるみたいです。
- 属性渡し
- tags経由渡し
- parent渡し
- Observer渡し
属性渡し
独自タグの属性に値を渡す方式です。
<mytag name="邪王炎殺黒龍波"/>
受け取る側は opts を使います。
<mytag>
<h1>技名:{opts.name}</h1>
</mytag>
渡す値を変数化して動的に変えることも可能です。
<bosstag>
<mytag name="{skill}"/>
<script>
this.skill = "霊丸";
changeSkill() {
this.skill = "ローズウィップ";
}
</script>
</bosstag>
React であれば Props の Validation が定義できるのですがそこはご愛嬌。
※何故か自分の環境では変数経由の属性渡しが上手くいったりいかなかったりする……。
tags経由渡し
JavaScriptのコードからも子供コンポーネントにアクセス可能です。
<mytag>
<h1>技名:{name}</h1>
<script>
this.name = "霊剣";
</script>
</mytag>
<bosstag>
<mytag/>
<button onClick="{changeSkill}">PUSH</button>
<script>
changeSkill() {
//独自タグ名が大文字だったとしても小文字指定になる
this.tags.mytag.name = "修羅旋風拳";
}
</script>
</bosstag>
ソースのコメントにも書いてますが tags 以下で指定するタグ名は全て小文字です。
便利な反面、子供側のコンポーネントからすると、変数がいつ誰に書き換えられるか分からないので意図しない挙動に繋がりそうな気がしています。ご利用は計画的に。
parent経由渡し
これは tags の逆パターン。子供が親にアクセス方法です。
<bosstag>
<h1>技名:{name}</h1>
<mytag/>
<script>
this.name = "霊光鏡反衝";
</script>
</bosstag>
<mytag>
<button onClick="{callBoss}">PUSH</button>
<script>
callBoss() {
this.parent.name = "霊光弾";
}
</script>
</mytag>
こちらも tags と同様にいつ誰に書き換えられるか分からない問題が起こりそうです。
Observer渡し
これは複数階層から成るアプリだと便利な機能ですね!識別子を付けてアプリ全体に通知を流すことで、その識別子を監視しているコンポーネント全てと連携可能になります。どれだけ階層が離れていても通知は実行できる点がポイントですかね。
<script>
var observer = riot.observable();
</script>
<bosstag>
<button onClick="{sendMessage}">PUSH</button>
<script>
sendMessage() {
observer.trigger("skill", "裂蹴紅球波");
}
</script>
</bosstag>
<mytag>
<h1>技名:{name}</h1>
<script>
this.name = "風華円舞陣";
var self = this;
observer.on("skill", function(text) {
self.name = text;
});
</script>
</mytag>
所感
基本的には属性渡しベースで作っていくのが無難?という気がしています。属性名やoptsを見れば外部とのインタフェースが明確に分かりますし、意図しない挙動も比較的起きにくいでしょう。階層構造が深くなってきた場合は、Observer渡しを適宜使っていく……感じなんでしょうかね。
ReactでいうRedux相当のものがRiotにもありそうなので、もう少し調べてみようと思います。