3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Turbolinks管理下でReactを使う

Last updated at Posted at 2018-12-01

いつの間にかTurbolinksおじさんと化している気もするのですが、今回はTurbolinksを使っているプロジェクト内にReactで作ったウィジェットを埋め込んだ話をしていきます。

Turbolinks~SSRとは逆向きから

JavaScriptで全ページを構築するSPAではファーストビューが遅いという問題があって、JavaScriptをサーバサイドでも実行するSSRを行うことでファーストビューを改善しています。

一方で、Turbolinksは出発点が「HTMLで書かれたWebページ」で、JavaScriptではページ遷移だけに介入して別なHTMLを生成することで、HTML全体のリロードを回避する、という構成になっています。

ちょっとだけReact

以前に書きましたが、React.jsはページ全体に対して組み込むだけではなく、ページのパーツとして一部だけに組み込むことも可能です。

ライフサイクルを見計らって

ただ、途中でページが入れ替わる以上、普通はあまりする機会の来ない「ページからの撤去」も必要となります。まずは、HTMLの生成・変更・削除に関連するライフサイクルを洗い出してみます。

ライフサイクル 遷移前のDOM 遷移後のDOM
turbolinks:before-cache ここのイベントで変更したあとのものがキャッシュされる (まだ存在しない)
turbolinks:before-render この直後に画面から消える 裏画面としてDOM操作が可能
turbolinks:render (画面から消えている) document.bodyとして表示される

ノーマルコース

新しいページにはめ込むコンポーネントをturbolinks:renderではめ込むことにした場合、比較的使いやすい感じになります。ただし、いったん表示されてからマウントするので、チラツキが発生します。

セットしたまま遷移すると、ページに存在しないコンポーネントだけが残ってしまったり、(Reactの場合はそこまで問題ないかもしれませんが)イベントが消えたDOMノードだけがキャッシュされたりといった不都合が生じるので、アンマウントが必要となります。turbolinks:before-cacheturbolinks:before-renderの両方でReactDOM.unmountComponentAtNodeしておけばいいでしょう(ReactDOM.unmountComponentAtNodeは、Reactがマウントされていないエレメントに対して実行しても何も起きません)。

上級コース

turbolinks:before-renderでは、遷移先の画面の<body>が形成されて、e.target.newBodyとしてイベントからも取れるので、ここでマウントすれば、表示前にReactを構築してしまうことができます。

ただ、マウントされた<body>document.bodyではないので、Reactの中からdocument.getElementByIdなどのようなことをしている場合、うまく動かなくなるのは要注意です。

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?