useSWRに出会うまでは、fetchの回数をなるべく減らしたいと思っていた
とにかくプログラマが考えることが少なくなる
Componentが表示された時に古いデータのrevalidateが行われ、
新しいデータがfetchされたら勝手にViewが更新されるため
一度useSWRを知ってしまうと、もうこれが当たり前になってしまう
なぜ僕はこういうアプローチを今まで思いつけなかったんだろうか?
Hooks以後のクライアントサイドStoreについて、かなり調べていたし、いくつかのライブラリを試したり、内部の実装を読んだり、自分でもラッパーを書いたりもしたが
このシンプルなアイデアを、全く思いつけなかった
多分、fetchの回数をなるべく減らしたいと思っていたんだと思うteramotodaiki.icon
fetchの回数をなるべく減らしたいと思っていた
これは大きく2つの目的があるがあると思う
ユーザー体験を良くするため
サーバーからの転送量を減らすため
困窮していたという程ではないが、Firestoreの無料枠は過ぎていたし、コスパが良いに越したことはないのだ fetchを行う理由も2つに分けられると思う
①最初に行うfetch
②前回取得したデータが古くなっている(かも知れない)ために行うfetch
Reduxに代表されるJavaScriptのクライアントサイドStoreは、fetchを減らすために存在している(と思う)
これは過言かも知れないが、大きな目的の一つではあると思う
もしもfetchのコスト(時間、CPU、サーバー料金etc)が0なら、データが必要になったときに呼べばいいのだから
キャッシュも、pushも、subscribeも、Storeも、fetch(を起点とするあらゆる計算)のコストが高いから存在している
Componentは増えるが、fetchは増やしたくない
だからデータを取り回す必要があり、Storeの必要性が生まれる
https://gyazo.com/ae1e2b88d389cf84eb1b222d28a03836
Recoilは、Storeとfetcherを内包することで、fetchの回数を適切に抑えてくれる
「①最初に行うfetch」は、どんなライブラリを使っても大抵シンプルに書ける
「②前回取得したデータが古くなっている(かも知れない)ために行うfetch」は、再fetchのロジックを考える必要がある
ロジックを考えるには、
いつデータが更新されるのか
ユーザーにとって、そのデータが常に最新であることがどのくらい重要か
どのくらいで古くなるのか
別のfetchによって既に取得され、Storeに格納されていないか
など、様々な観点からデータの特性を考察し、ロジックを考えていく
良い更新アルゴリズムが閃いたとしても、Storeライブラリの表現力が足りなければ、書くのは難しい
ロジック側の都合でコンポーネントライフサイクルと密結合になることも多い
僕がReduxやRecoilでコードを書く時、9割方はここに時間を使っていたのではないかと思うteramotodaiki.icon
useSWRは、②のロジックを「パターン化」した
useSWRのロジックについて、ここで詳しくは説明しないが、
useSWRは、②のロジックを、ライブラリ利用者が実装しなくても済む設計になっている
いくつかのオプションを指定すれば、あとはuseSWRが再fetchして、更新してくれる
僕がuseSWRを画期的だと思ったポイントはここteramotodaiki.icon
hooksをインターフェースにしたことで、コンポーネントのライフサイクルと連携してくれる点もまた画期的である
データの性質を深く理解して書いた更新ロジックに比べて、fetchの回数は増える可能性が高いだろう
つまり、どっちがいいかという話である
極めて効率的な100行の更新ロジックと、
0~3個程度のオプションを指定するだけで、どんなユースケースにも大体対応できる汎用的な更新ロジック
まとめ
これまでのライブラリは、Storeに「どうデータを置くか」に主眼をあてたものが多かったと思う
重要なのはデータを取り出すインターフェースだと気づいた
useSWRのアプローチは他のライブラリにも転用可能である
多くのhooksライブラリがuseSWRのようなアプローチを採用していくだろう