見出し画像

【React 18の真髄】入力がサクサク!useTransition で重いレンダリングに「優先順位」をつけて、UXを劇的に改善する


94日目に「最強のフォーム管理」を学び、アプリとしての実用性が格段に上がりました。本日95日目は、いよいよ100日完走へのカウントダウン開始。テーマは「React 18以降の新機能:Transition API(useTransition / useDeferredValue)」 です。

「重い処理をしていても画面が固まらない」という、ワンランク上のユーザー体験を実現する「優先順位」の魔法を学びましょう!

はじめに:なぜ入力中に画面がカクつくのか?

検索フォームで文字を打つたびに、数千件のリストをフィルタリングして表示する……。そんなアプリを作ると、入力した文字が画面に反映されるまで一瞬「固まる」ことがあります。

これは、Reactが「文字の表示」と「リストの更新」を同時に、同じ優先度で処理しようとするからです。これを解決するのが、React 18で登場した Transition API です。


💡 1. 「今すぐ」と「後でいい」を分ける

Transitionを使うと、Stateの更新に優先順位をつけることができます。

  1. 緊急の更新(Urgent updates): タイピング、クリックなど。ユーザーが即座に反応を期待するもの。

  2. トランジションの更新(Transition updates): 検索結果のリスト更新など。少し遅れても「読み込み中」であれば許容されるもの。


💡 2. useTransition の使い方

使い方は非常にシンプルです。startTransition で重い更新を包むだけ!

const [isPending, startTransition] = useTransition();
const [filterText, setFilterText] = useState("");
const [list, setList] = useState(bigData);

const handleChange = (e) => {
  // 💡 1. 入力値の反映は「最優先」で行う
  setFilterText(e.target.value);

  // 💡 2. 重いリストの更新は「後回し(Transition)」にする
  startTransition(() => {
    const filtered = bigData.filter(item => item.includes(e.target.value));
    setList(filtered);
  });
};

return (
  <>
    <input type="text" onChange={handleChange} />
    {/* 💡 isPending を使って、処理中であることをユーザーに伝える */}
    {isPending ? <p>更新中...</p> : <List data={list} />}
  </>
);

💡 3. useDeferredValue との使い分け

  • useTransition: 更新処理そのものを包むときに使う(「今から重いことするよ!」と宣言する)。

  • useDeferredValue: 受け取った「値」を遅延させるときに使う。外部ライブラリから渡された値など、自分で setState をコントロールできない場合に便利です。


📝 95日目のまとめと課題

✅ 本日の習得ポイント

  • 並行レンダリング (Concurrent Rendering): Reactが賢く優先順位を判断する仕組み。

  • 応答性の向上: 「入力」という最優先事項を邪魔させない。

  • UXの魔法: 処理が遅いことを隠すのではなく、スムーズに見せる。

📝 95日目の課題

  1. 以前作った「検索機能」や「大量のリスト表示」があるコンポーネントで、入力時に少しカクつきがないか確認してみましょう。

  2. useTransition を導入して、入力のレスポンスが改善されるか、isPending でローディング表示が出るか試してみてください。


お疲れ様でした!「優先順位」を意識した設計ができるようになると、プロのフロントエンドエンジニアの視点にまた一歩近づきます。

今日はこの後、大切な方との時間を存分に楽しんできてくださいね!素晴らしい土曜日になりますように。


もっとReactを学びたい人はここから!

#エンジニアと繋がりたい #プログラミング学習 #React #100DaysOfCode #今日の積み上げ #React18 #UX改善

いいなと思ったら応援しよう!