さて、またもや今更感ありますが、、、、
デモアプリを作ってuseTransitionの動作を見ていこうと思います。
useTransitionって何?
状態変更に伴う画面遷移やコンポーネントの表示切り替え時、
今の画面を保持しつつ、次の画面を裏で準備(レンダリング)させるための機能
です。
人間の操作感はそのままに、裏でレンダリング終わるまでさっきの表示をずっと出しておいて。。。という具合です。
useTransitionは、遷移が進行中かどうかを示す isPending
と、遷移を開始するための startTransition
関数を得ます。
startTransition
コンポーネントのレンダリングとstate更新を遅らせる機能で、主な機能は遅延された更新とレンダリングの遅延です。
遅らせるstate、遅らせないstateと分けること、つまり状態更新の優先順位を任意で設定
できます。
isPending
遅延された更新が完了するまでの間、trueになります。
更新が完了すると、falseに戻ります。これにより、UIにローディングインジケータやスピナーを表示することができます。
早速試してみましょう
import { useState, useCallback, useTransition } from "react";
function createLargeArray() {
const array = new Array(20000).fill(0).map((_, index) => index + 1);
return array;
}
function App() {
const [isPending, startTransition] = useTransition();
const [counter, setCounter] = useState(0);
const [array, setArray] = useState([]);
const handleClick = useCallback(async () => {
const largeArray = createLargeArray();
startTransition(() => {
setArray(largeArray);
});
}, [startTransition]);
return (
<div className="App">
<h1>useTransition</h1>
<p>{counter}</p>
<button
onClick={() => {
setCounter((c) => c + 1), handleClick();
}}
>
Create array
</button>
{isPending && <p>isPending...</p>}
<ul>
{array.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
export default App;
li内が表示されるまで、isPending...
が表示され続けました。
下記2点が確認できました。
- カウントは即座に増えている
-
startTransition
内のstateが整うまで、isPendingを出している
では、カウントも startTransition
の中に入れるとどうなるのでしょうか?
const handleClick = useCallback(async () => {
const largeArray = createLargeArray();
startTransition(() => {
+ setCounter((c) => c + 1);
setArray(largeArray);
});
}, [startTransition]);
想像通り、配列の表示と同時に表示が変わりました。
まとめ
useTransitionは、応答性の向上や高コスト処理の制御に効果的で、準備中にローディングインジケータ表示するなどしてユーザーに今何が起こっているのかを知らせることができます。
一度触ってみてくださいね!
参考 :
Reactのトランジションで世界を分岐させるハンズオン
https://zenn.dev/uhyo/books/react-concurrent-handson-2/viewer/mixing
Reactの2種類の新フック「useTransition」と「useDeferredValue」を最速で理解する(プレビュー版
https://qiita.com/uhyo/items/6be96c278c71b0ddb39b#usetransition