23
9

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.

React18で新しく導入されたuseTransitionとuseDefferedValueの使い分け

Last updated at Posted at 2022-07-18

現在QiitaではQiita Engineer Festa 2022が開催中です。当記事もエントリーしております

最近React18がリリースされたようです

React18に関しては@uhyoさんに非常に参考になる記事を投稿していただいてます

ただ、いまいちuseTransitionとuseDefferedValueについて理解できていませんでした

そこで今回はこれらのHooksについて自分で内容をまとめてみたいと思っています

ちなみに、この記事ではconcurrent modeがリリースされるかもしれないが未定と書かれていますが、現在の正式リリースでは「mode」という考え方自体がなくなり、concurrent modeのみが標準として組み込まれています

useTransitionとuseDefferedValueの具体的な使い方

まずはそれぞれの使い方に関して確認しましょう

useTransiton

以下のコードはinputのテキスト入力後、レンダリングに関するリソースに余裕のある段階でコンポーネントが再レンダリングされるという仕様になっています

つまりテキスト入力によるstate変更で引き起こされたpostsの再レンダリング優先度を低くするということです

export default function Home() {
    const [isPending, startTransition] = useTransition();
    const [keyword, setKeyword] = useState('');

    // Web APIからキーワードでフィルターした投稿一覧を取得
    const filteredProducts = filterKeyword(keyword);

    const updateKeyword = (e) => {
        startTransition(() => {
            setKeyword(e.target.value);
        });
    }

    return (
        <div id="app">
            <input type="text" onChange={updateKeyword} />
            {isPending && <p>Updating List...</p>}
            <PostsList posts={filteredPosts} />
        </div>
    );
}

useDeferredValue

続いてuseDeferredValueです

以下のコードは非同期で受け取ったPropsであるpostsを遅延してレンダリングを行っています

propsから値を受け取った時点ですぐにレンダリングするのはなく、postsをレンダリングする優先度を他のコンポーネントの描画優先度より下げる役割を担っています

function PostsList({ posts }) {
  const deferredPosts = useDeferredValue(posts);
  return (
    <ul>
      {deferredPosts.map((post) => (
        <li>{post}</li>
      ))}
    </ul>
  );
}

useTransitionとuseDefferedValueの違い

上記の例で示した通り「useTransition」はstateを更新する処理をwrapして遅延させるのに対し、「useDeferredValue」はstateの値をwrapして変更を遅延させています

以下基本的な使い分けに関しての結論です

keywordのように更新中のstateを読み込む必要があるのであればuseTransitionを、逆に読み込む必要がないのであればuseDeferredValueを使えば良いのではないかと思っています

それでは全ての非同期処理で受け取る値をuseTransitionやuseDeferredValueでwrapすればいいのではないかという話になるのですが、それは控えた方が良さそうです

先ほども述べたように「レンダリングに関するリソースに余裕のある段階」なので、非同期処理によるstate管理が煩雑になることが考えられます

あるときはstateが更新されているが、あるときはされていないというようなバグを引き起こさないためにも頻繁に使うようなhooksではなさそうです

あくまでもパフォーマンスチューニングという観点で、stateの変更を遅延させることが適切かどうか判断してから使用するようにしましょう

23
9
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
23
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?