環境
フロント:React v18系
バック:自作APIサーバー
ReactでTanstak QueryのuseQueryを
以下の設定で行なっていました。
const {data :topics} = useQuery({
queryKey:['topics'] ,
queryFn:() => getTopic()
});
queryFnに定義しているクエリ関数はこちら。
topicを取得するクエリです。
export const getTopic = async() => {
try{
const result = await axios.get(URL)
return result.data
}catch(err){
return err
}
}
問題点
これで正常に動いていたのですが、このクエリを使っていない別ページに遷移し、
元に戻った際に下記のエラーがconsoleに発生し、画面が表示されなくなりました。
A component suspended while responding to synchronous input.
This will cause the UI to be replaced with a loading indicator.
To fix, updates that suspend should be wrapped with startTransition.
エラー内容からググると、suspendを使え、とかusetrantisionを利用しようといった情報が見つかったのですが、それでも解決せず。(そもそもstartTrantisionをここで使うケースがあまり見当たりません)
最終的に、下記の修正で改善しました。
解決コード
const {data :topics} = useQuery({
queryKey:['topics'] ,
queryFn:async () => { //この2行が変更点
return getTopic();
}
});
この書き方であれば該当の事象は発生しなくなりました。
非同期関数を利用する場合、queryFnの関数はプロミスを返す必要があるようです。
非同期の関数なのに、queryFnで使う時に普通に書いてしまったのでコンポーネント描写を止めてしまっていた、ということなのだと思われます。
確かに公式でもasyncを使った書き方もあり、またqueryFnはpromiseを返す関数を書くものだと書かれているようです。
A query function can be literally any function that returns a promise. The promise that is returned should either resolve the data or throw an error.
では、なぜ普通の書き方もあるのか?というところは
ちょっと原因を調べきれてないですが、一旦備忘録的に記載。