LoginSignup
17
18

More than 5 years have passed since last update.

現在(2.2.4)のRiot.jsのifステートメントはfalseでも実行されてしまう件とその回避法

Last updated at Posted at 2015-10-09

Riot.jsに魅せられてしまったemadurandalさんですこんにちは。

Riot.jsいいですよね。Reactから移ってきたのですがもう戻れません。

  • 記述がとにかくシンプルかつHTMLセントリック(デザイナーさんにとっても抵抗少ない)。
  • HTMLとJavaScriptだけでなく、CSSまでコンポーネントにカプセル化できる。
  • サイズが超小さい(モバイルにも優しい)

などなど、メリットは計り知れません。ただ、まだ若いプロジェクトなので、罠もそれなりにありますね。

今回はそんな罠の一つ。表題の件です。

例えばですね。↓こういうのがあったとしましょう。

<my-app>
  <my-heavy-ui if={enable} arg={opt.foo} />

  this.enable = false;
</my-app>

これ、if=false なわけですが、実はページ上見えなくなるだけで、実際は<my-heavy-ui>は実行されてしまいます。取るに足らない小さい部品ならいいんですが、色々処理するような重たい部品だった場合は、嫌ですよね。

それに、再帰的に同じコンポーネントを使いたい場合は、ifで処理を止めようとしても、if=falseでも実行されてしまうために、結局延々とネスト処理が続いてスタックオーバーフローになってしまいます。

<my-folder>
  <my-folder if={!isLeaf()} arg={opt.foo} />  ←ifだとうまくいかない!

  this.isLeaf = function(){
    // 末尾かどうかを判定する処理
  }
</my-folder>

では、どうすればいいのか。eachステートメントを使います。

<my-app>
  <my-heavy-ui each={enable ? [true]:[]} arg={parent.opt.foo} />

  this.enable = false;
</my-app>
<my-folder>
  <my-folder each={!isLeaf() ? [true]:[]} arg={parent.opt.foo} />  
  this.isLeaf = function(){
    // 末尾かどうかを判定する処理
  }
</my-folder>

どういうことかというと、enable!isLeaf()が真の時は、要素数1(trueとか適当な値が1個入っている)の配列になるため、1個だけコンポーネントが生成されるのです。偽の場合は、空の配列なので、コンポーネントは生成されません。これで、擬似的にifっぽいことをしています。
注意点としては、eachステートメントを使うので、opts.fooparent.opts.fooにしないといけませんね。

これなら、重たい部品が実は生成されていたとか、コンポーネントの再帰がスタックオーバーフローだよウワァァァンとかいうことがなくなります。

私の場合、このやり方をするようにしてから、自作のチャットシステムの表示パフォーマンスがざっと体感で数倍〜10倍くらい速くなりました(ifを多用しまくっていたせいもありますが)。
特に、IE系はパフォーマンスの改善が顕著です。みなさま、騙されたと思ってぜひお試しを!

しかし、このifの挙動、なんなんですかね。Riot.jsのソース読んだり、Githubコミュニティに入り浸っているほど、深く足を突っ込んでいるわけでもないので、よくわかりません。

めんどくさいので、将来のバージョンでは仕様を変えて欲しいところですね。

2015/10/26追記

Riot.js公式サイトの日本語翻訳プロジェクトを主導され、ikki などのRiot拡張なども手がけていらっしゃる、国内におけるRiotの第一人者 @cognitom さんにこのifの挙動について質問したところ、こんなお答えがありました。

なるほど、そうでしたか……。
実装上のやむない理由により、今のような仕様になっているのですね。もちろん、本来のifの役割として望ましい挙動でないことは開発の方々も認識されているわけなので、いずれ解決されることを期待したいですね。

それでは、皆様もよいRiot.jsライフを!^o^/

17
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
18