28
6

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 1 year has passed since last update.

React 18 の useTransition を触ってみる

Last updated at Posted at 2023-04-24

さて、またもや今更感ありますが、、、、
デモアプリを作って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;

タイトルなし.gif

li内が表示されるまで、isPending... が表示され続けました。
下記2点が確認できました。

  • カウントは即座に増えている
  • startTransition内のstateが整うまで、isPendingを出している

では、カウントも startTransitionの中に入れるとどうなるのでしょうか?

  const handleClick = useCallback(async () => {
    const largeArray = createLargeArray();
    startTransition(() => {
+     setCounter((c) => c + 1);
      setArray(largeArray);
    });
  }, [startTransition]);

2.gif

想像通り、配列の表示と同時に表示が変わりました。

まとめ

useTransitionは、応答性の向上や高コスト処理の制御に効果的で、準備中にローディングインジケータ表示するなどしてユーザーに今何が起こっているのかを知らせることができます。
一度触ってみてくださいね!

参考 :
Reactのトランジションで世界を分岐させるハンズオン
https://zenn.dev/uhyo/books/react-concurrent-handson-2/viewer/mixing

Reactの2種類の新フック「useTransition」と「useDeferredValue」を最速で理解する(プレビュー版
https://qiita.com/uhyo/items/6be96c278c71b0ddb39b#usetransition

28
6
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
28
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?