Recoil の Query Refresh Pattern を useRecoilRefresher_UNSTABLE に置き換える
MAD 事業部の高橋ゆうきです。
以前 Recoil でつくるお天気アプリ という記事で、Recoil の Query Refresh Pattern を紹介しました。
バージョン 0.5.0 からは、それを置き換えることができる useRecoilRefresher_UNSTABLE
が実装されていたので、書き換えることにしてみました。
準備
以前使っていたリポジトリを再利用します。
まずはパッケージをまとめて更新してしまいましょう、ついでにバージョンも固定してしまいます。
yarn upgrade-interactive --latest
できた PR は以下になります。このまま yarn start
を叩いても問題なく起動しました。
useRecoilRefresher_UNSTABLE
useRecoilRefresher_UNSTABLE
が実装されたので、以前作成した useRefreshCityId
を置き換えていきます。置き換えた結果は以下になります。
まずは Query Refresh Pattern の実装で使用した atomFamily
を削除していきます。
都市の天気をリロードできるように変更 #1 の内容を revert してしまうのが早いです。
refresh するには useRecoilRefresher_UNSTABLE
で戻される関数を実行するだけです。引数には RecoilValue
をとるため weatherState
を与えます。
import React, { useState } from "react"; import { useRecoilRefresher_UNSTABLE, useSetRecoilState } from "recoil"; import { cityIdState } from "../states/rootStates/cityId"; import { weatherState } from "../states/rootStates/weather"; import { cities, CityId } from "../utils/city"; export const WeatherForm: React.VFC = () => { const [cityId, setCityId] = useState<CityId>(); const setStateCityId = useSetRecoilState(cityIdState); const refresh = useRecoilRefresher_UNSTABLE(weatherState); const changeCity = (e: React.ChangeEvent<HTMLSelectElement>) => { const id = e.currentTarget.value as CityId; setCityId(id); }; const submit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); setStateCityId(cityId); }; return ( <form onSubmit={submit}> <select onChange={changeCity}> <option value="">選択なし</option> {cities.map((city) => ( <option value={city.id} key={city.id}> {city.name} </option> ))} </select> <button type="submit">submit</button> <button onClick={() => refresh()}>refresh</button> </form> ); };
変更点は以上です。Query Refresh Pattern と比べると状態の更新のためだけに存在していた atomFamily
が不要になっているため、かなりわかりやすくなりました。
Query Refresh Pattern
ここまで Query Refresh Pattern と書いてきましたが、現在のドキュメントでは Query Refresh Pattern の名称が消え、Use a Request ID と表記されています。
useRecoilRefresher_UNSTABLE
はその関数名についている suffix を見ればわかるように、UNSTABLE であるため、従来どおり Use a Request ID を使って取得する選択肢が完全になくなったというわけではありません。
さいごに
Recoil を実際にプロジェクトで使ったことはないのですが、今の時点ですべての状態を Recoil で済ませるというのは若干厳しいものがあるかなという印象です(個人的な意見です)。
おおよそ 10 ヶ月ぶりに自分のコードを見たわけですが、とりわけやはり Query Refresh Pattern 部分はだいぶ理解に苦しむところがありました。今回は非常にシンプルなアプリですので問題になりませんでしたが、規模が大きいものであればこうはいかなかったかもしれません。
useRecoilRefresher_UNSTABLE
はより使いやすくなる一歩なのですが、実際のプロジェクトで UNSTABLE な関数を使うというのもその要因の一つです。