use:レンダー中にリソースを読み取る新しいAPI
use
はPromiseやContextなどのリソースから値を読み取るための新しいAPIです。現時点では、use
に指定できるリソースはPromiseかContextのいずれかです。Contextのほうが直感的なため、先にそちらから見ていきましょう。
useでContextを読み取る
ContextはReactで状態管理を行う仕組みの一つで、祖先コンポーネントで指定された値を、子孫コンポーネントで参照できるようにする機構です。典型的には「UI テーマ」など、広範囲に影響を与える変数で、propsで受け渡すと煩雑になる状態管理に使われます。ただしグローバル変数に近いものなので、乱用は禁物です。
これまで子孫コンポーネントでContextの値を読み取るには、useContext
フックを使ってきましたが、これをuse
で置き換えることができます。
// テーマコンテキスト const ThemeContext = createContext("light"); // テーマを変更するコンポーネント function ThemeChanger() { const [theme, setTheme] = useState("light"); return ( <div> <button onClick={() => setTheme((prev) => (prev === "light" ? "dark" : "light"))}> テーマ変更 </button> <ThemeContext value={theme}> <ThemeDisplay /> </ThemeContext> </div> ); } // テーマを使用するコンポーネント function ThemeDisplay() { // const theme = useContext(ThemeContext); // 従来の useContext を使った書き方 ... (1) const theme = use(ThemeContext); // React 19~の use を使った書き方 ...(2) return <p>テーマ: {theme}</p>; } function App() { return <ThemeChanger />; }
上の例ではuseContext
を使った書き方((1))をuse
を使った書き方((2))に置き換えています。いずれも同じように動作します。
フックであるuseContext
は、必ずコンポーネントの直下で呼び出す必要があり、if文などに含めたり、早期リターンの後には書けませんでした。use
はいわゆる「フック」ではなく、if文やループなどの中でも呼び出すことができます。
リスト4のように、use
は早期リターンの後でも使えるため、記述の自由度が高くなります。このため、今後はuse
を使うことが推奨されています。
// テーマを使用するコンポーネント function ThemeDisplay() { if (someCondition) { return null; // 早期リターン } const theme = use(ThemeContext); // 早期リターン後は、useContextはNGだが、useならOK return <p>テーマ: {theme}</p>; }
なお、これまでContextでは<Context.Provider>
を使って下層のコンポーネントに適用していましたが、React 19からは<Context>
を直接指定するように変更されました。従来の<Context.Provider>
は将来のバージョンで非推奨になる予定のため、注意が必要です。
const ThemeContext = React.createContext("light"); function App() { return ( // <ThemeContext.Provider value="dark"> {/* React 18 までの書き方 */} // <ThemeDisplay /> // </ThemeContext.Provider> <ThemeContext value="dark"> {/* React 19 以降の書き方 */} <ThemeDisplay /> </ThemeContext> ); }
useでPromiseの値を読み取る
もう一つのuse
の用法が、Promiseを渡して、その結果を読み取ることです。「awaitすればいいのでは?」と思われるかもしれませんが、通常の関数コンポーネントは同期関数のため、直接的にawaitは使用できません。use
の導入により、関数コンポーネント内でPromiseから結果を取り出せるようになります。
use
はReact 18から導入されたSuspenseの仕組みを前提としており、渡されたPromiseが未解決の間、use
はSuspendします。つまり、このuse
を有効に使うためには、コンポーネントの上層でSuspenseが存在しなければなりません。
import { use, Suspense } from "react"; function DataDisplay({ dataPromise }) { // useを使ってPromiseからデータを取り出す // ※Promiseが未解決の間は中断されてSuspenseのフォールバックが表示される const dataContent = use(dataPromise); return <p>データ: {dataContent}</p>; } export function DataContainer({ dataPromise }) { return ( // Promiseが未解決の間はフォールバックが表示される <Suspense fallback={<p>読み込み中...</p>}> <DataDisplay dataPromise={dataPromise} /> </Suspense> ); }
まとめ
今回はReact 19の新しいAPIについて紹介しました。前回のuseActionState
フックや<form>
アクションに加え、useOptimistic
やuseFormStatus
フック、use
といった新しく便利なAPIが追加されていました。
次回はReact 19で正式にサポートされたReact Server Componentsやその他の変更点について紹介していくので、ご期待ください。