use - This feature is available in the latest Canary

Canary

use γƒ•γƒƒγ‚―γ―ηΎεœ¨γ€React οΏ½? Canary γŠγ‚ˆγ³ experimental チャンネルで�?γΏεˆ©η”¨ε―θƒ½γ§γ™γ€‚React οΏ½?γƒͺγƒͺースチャンネルに぀いてはこけらをご覧ください。

use γ―γƒ—γƒ­γƒŸγ‚Ή (Promise) γ‚„γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγͺど�?γƒͺソースから倀をθͺ­γΏε–γ‚‹γŸγ‚οΏ½? React フックです。

const value = use(resource);

γƒͺフゑレンス

use(resource)

γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆε†…γ§ use γ‚’ε‘Όγ³ε‡Ίγ—γ€γƒ—γƒ­γƒŸγ‚Ήγ‚„γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγͺど�?γƒͺソースから倀をθͺ­γΏε–γ‚ŠγΎγ™γ€‚

import { use } from 'react';

function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
const theme = use(ThemeContext);
// ...

δ»–οΏ½?あらゆる React フックとは異γͺγ‚Šγ€use は if οΏ½?γ‚ˆγ†γͺγƒ«γƒΌγƒ—γ‚„ζ‘δ»Άζ–‡ε†…γ§γ‚‚ε‘Όγ³ε‡Ίγ™γ“γ¨γŒγ§γγΎγ™γ€‚δ»–οΏ½? React γƒ•γƒƒγ‚―γ¨εŒζ§˜γ«γ€use γ‚’ε‘Όγ³ε‡Ίγ™ι–’ζ•°γ―γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΎγŸγ―γƒ•γƒƒγ‚―γ§γͺγ‘γ‚Œγ°γͺγ‚ŠγΎγ›γ‚“γ€‚

γƒ—γƒ­γƒŸγ‚Ήγ‚’εΌ•ζ•°γ«γ—γ¦ε‘Όγ³ε‡Ίγ—γŸε ΄εˆγ€use フックは Suspense やエラーバウンダγƒͺ (error boundary) と協θͺΏγ—γ¦ε‹•δ½œγ—γΎγ™γ€‚use γ‚’ε‘Όγ³ε‡Ίγ™γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ―γ€use γ«ζΈ‘γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚ΉγŒδΏη•™δΈ­ (pending) γ§γ‚γ‚‹ι–“γ€γ‚΅γ‚Ήγƒšγƒ³γƒ‰ (suspend) します。use γ‚’ε‘Όγ³ε‡Ίγ™γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒγ‚΅γ‚Ήγƒšγƒ³γ‚Ήγƒγ‚¦γƒ³γƒ€γƒͺγ§γƒ©γƒƒγƒ—γ•γ‚Œγ¦γ„γ‚‹ε ΄εˆγ€γƒ•γ‚©γƒΌγƒ«γƒγƒƒγ‚―γŒθ‘¨η€Ίγ•γ‚ŒγΎγ™γ€‚γƒ—γƒ­γƒŸγ‚ΉγŒθ§£ζ±Ί (resolve) γ•γ‚ŒγŸζ™‚η‚Ήγ§γ€γ‚΅γ‚Ήγƒšγƒ³γ‚Ήγƒ•γ‚©γƒΌγƒ«γƒγƒƒγ‚―γ―γ€use γƒ•γƒƒγ‚―γ‹γ‚‰θΏ”γ•γ‚ŒγŸγƒ‡γƒΌγ‚Ώγ‚’δ½Ώη”¨γ—γ¦γƒ¬γƒ³γƒ€γƒΌγ•γ‚ŒγŸγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?ε†…οΏ½?�に�?γζ›γ‚γ‚ŠγΎγ™γ€‚use γ«ζΈ‘γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚ΉγŒζ‹’ε¦ (reject) γ•γ‚Œγ‚‹γ¨γ€ζœ€γ‚‚θΏ‘γ„γ‚¨γƒ©γƒΌγƒγ‚¦γƒ³γƒ€γƒͺοΏ½?γƒ•γ‚©γƒΌγƒ«γƒγƒƒγ‚―γŒθ‘¨η€Ίγ•γ‚ŒγΎγ™γ€‚

さらに例を見る

εΌ•ζ•°

θΏ”γ‚Šε€€

use γƒ•γƒƒγ‚―γ―γ€γƒ—γƒ­γƒŸγ‚ΉοΏ½?θ§£ζ±Ίγ•γ‚ŒγŸε€€γ‚„γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγͺど、γƒͺソースからθͺ­γΏε–γ£γŸε€€γ‚’θΏ”γ—γΎγ™γ€‚

注意点

  • use γƒ•γƒƒγ‚―γ―γ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΎγŸγ―δ»–οΏ½?γƒ•γƒƒγ‚―ε†…γ§ε‘Όγ³ε‡Ίγ™εΏ…θ¦γŒγ‚γ‚ŠγΎγ™γ€‚
  • γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§γƒ‡γƒΌγ‚Ώγ‚’γƒ•γ‚§γƒƒγƒγ™γ‚‹ιš›γ―γ€use γ‚ˆγ‚Šγ‚‚ async と await γ‚’ε„ͺε…ˆγ—γ¦δ½Ώη”¨γ—γ¦γγ γ•γ„γ€‚async と await は await γŒε‘Όγ³ε‡Ίγ•γ‚ŒγŸεœ°η‚Ήγ‹γ‚‰γƒ¬γƒ³γƒ€γƒΌγ‚’ε†ι–‹γ—γΎγ™γŒγ€use γ―γƒ‡γƒΌγ‚ΏγŒθ§£ζ±Ίγ—γŸεΎŒγ«γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’ζœ€εˆγ‹γ‚‰γƒ¬γƒ³γƒ€γƒΌγ—γΎγ™γ€‚
  • γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§γƒ—γƒ­γƒŸγ‚Ήγ‚’δ½œζˆγ™γ‚‹γ‚ˆγ‚Šγ‚‚γ€γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§γƒ—γƒ­γƒŸγ‚Ήγ‚’δ½œζˆγ—γ¦γγ‚Œγ‚’γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ«ζΈ‘γ™γ‚ˆγ†γ«γ—γ¦γγ γ•γ„γ€‚γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§δ½œζˆγ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚Ήγ―γ€γƒ¬γƒ³γƒ€γƒΌγ”γ¨γ«ε†δ½œζˆγ•γ‚ŒγΎγ™γ€‚γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ«ζΈ‘γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚Ήγ―γ€ε†γƒ¬γƒ³γƒ€γƒΌι–“γ§δΈε€‰γ§γ™γ€‚γ“γ‘γ‚‰οΏ½?例を参照してください。

使用法

use γ§γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγ‚’θͺ­γΏε–γ‚‹

γ‚³γƒ³γƒ†γ‚―γ‚ΉγƒˆγŒ use γ«ζΈ‘γ•γ‚ŒγŸε ΄εˆγ€useContext γ¨εŒζ§˜γ«ε‹•δ½œγ—γΎγ™γ€‚useContext γ―γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?γƒˆγƒƒγƒ—γƒ¬γƒ™γƒ«γ§ε‘Όγ³ε‡Ίγ™εΏ…θ¦γŒγ‚γ‚ŠγΎγ™γŒγ€use は if γ‚„ for γͺど�?村仢式�?δΈ­γ§γ‚‚ε‘Όγ³ε‡Ίγ™γ“γ¨γŒγ§γγΎγ™γ€‚use γ―γ‚ˆγ‚ŠζŸ”θ»Ÿγ§γ‚γ‚‹γŸγ‚γ€useContext γ‚ˆγ‚Šγ‚‚ε„ͺε…ˆηš„γ«δ½Ώη”¨γ—γ¦γγ γ•γ„γ€‚

import { use } from 'react';

function Button() {
const theme = use(ThemeContext);
// ...

use γ―γ€ζΈ‘γ—γŸγ‚³γƒ³γƒ†γ‚―γ‚ΉγƒˆοΏ½?ε€€γ‚’θΏ”γ—γΎγ™γ€‚γ‚³γƒ³γƒ†γ‚―γ‚ΉγƒˆοΏ½?ε€€γ‚’ζ±ΊοΏ½?οΏ½γ™γ‚‹γŸγ‚γ«γ€React γ―γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγƒ„γƒͺγƒΌγ‚’δΈŠζ–Ήε‘γ«ζ€œη΄’γ—γ€ε½“θ©²γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγ«ε―ΎεΏœγ™γ‚‹ζœ€γ‚‚θΏ‘γ„γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγƒ—γƒ­γƒγ‚€γƒ€ (context provider) を見぀けます。

Button γ«γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγ‚’ζΈ‘γ™γ«γ―γ€γγ‚ŒγΎγŸγ―γοΏ½?θ¦ͺγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?γ„γšγ‚Œγ‹γ‚’γ€ε―ΎεΏœγ™γ‚‹γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγƒ—γƒ­γƒγ‚€γƒ€γ§γƒ©γƒƒγƒ—γ—γΎγ™γ€‚

function MyPage() {
return (
<ThemeContext.Provider value="dark">
<Form />
</ThemeContext.Provider>
);
}

function Form() {
// ... renders buttons inside ...
}

プロバむダと Button οΏ½?間に何局�?γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒγ‚γ£γ¦γ‚‚ε•ι‘Œγ‚γ‚ŠγΎγ›γ‚“γ€‚Form οΏ½?内部�?どこかで Button が use(ThemeContext) を呼び出すと、倀として "dark" を受け取ることにγͺγ‚ŠγΎγ™γ€‚

useContext とは異γͺγ‚Šγ€use は if γͺど�?村仢式やループ�?δΈ­γ§ε‘Όγ³ε‡Ίγ™γ“γ¨γŒγ§γγΎγ™γ€‚

function HorizontalRule({ show }) {
if (show) {
const theme = use(ThemeContext);
return <hr className={theme} />;
}
return false;
}

use は if ζ–‡οΏ½?δΈ­γ‹γ‚‰ε‘Όγ³ε‡Ίγ•γ¦γ„γ‚‹γŸγ‚γ€ζ‘δ»Άδ»˜γγ§γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγ‹γ‚‰ε€€γ‚’θͺ­γΏε–γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚

落とし穴

useContext γ¨εŒζ§˜γ«γ€use(context) γ―εΈΈγ«γγ‚Œγ‚’ε‘Όγ³ε‡Ίγ—γ¦γ„γ‚‹γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?δΈŠε΄γ«γ‚γ‚‹ζœ€γ‚‚θΏ‘γ„γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγƒ—γƒ­γƒγ‚€γƒ€γ‚’ζŽ’γ—γΎγ™γ€‚δΈŠζ–Ήε‘γ«ζ€œη΄’γ™γ‚‹γŸγ‚γ€use(context) γ‚’ε‘Όγ³ε‡Ίγ—γ¦γ„γ‚‹γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆθ‡ͺδ½“γ«γ‚γ‚‹γ‚³γƒ³γƒ†γ‚―γ‚Ήγƒˆγƒ—γƒ­γƒγ‚€γƒ€γ―θ€ƒοΏ½?γ•γ‚ŒγΎγ›γ‚“γ€‚

import { createContext, use } from 'react';

const ThemeContext = createContext(null);

export default function MyApp() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
}

function Form() {
  return (
    <Panel title="Welcome">
      <Button show={true}>Sign up</Button>
      <Button show={false}>Log in</Button>
    </Panel>
  );
}

function Panel({ title, children }) {
  const theme = use(ThemeContext);
  const className = 'panel-' + theme;
  return (
    <section className={className}>
      <h1>{title}</h1>
      {children}
    </section>
  )
}

function Button({ show, children }) {
  if (show) {
    const theme = use(ThemeContext);
    const className = 'button-' + theme;
    return (
      <button className={className}>
        {children}
      </button>
    );
  }
  return false
}

γ‚΅γƒΌγƒγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγΈοΏ½?γƒ‡γƒΌγ‚Ώγ‚ΉγƒˆγƒͺγƒΌγƒŸγƒ³γ‚°

γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆ に props γ¨γ—γ¦γƒ—γƒ­γƒŸγ‚Ήγ‚’ζΈ‘γ™γ“γ¨γ§γ€γ‚΅γƒΌγƒγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ«γƒ‡γƒΌγ‚Ώγ‚’γ‚ΉγƒˆγƒͺγƒΌγƒŸγƒ³γ‚°γ™γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚

import { fetchMessage } from './lib.js';
import { Message } from './message.js';

export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>waiting for message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}

γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆ γ―γ€ε—γ‘ε–γ£γŸγƒ—γƒ­γƒŸγ‚Ή γ‚’ use γƒ•γƒƒγ‚―γ«ζΈ‘γ—γΎγ™γ€‚γ“γ‚Œγ«γ‚ˆγ‚Šγ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ―γ€γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒζœ€εˆγ«δ½œζˆγ—γŸγƒ—γƒ­γƒŸγ‚Ήγ‹γ‚‰ε€€γ‚’θͺ­γΏε–γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚

// message.js
'use client';

import { use } from 'react';

export function Message({ messagePromise }) {
const messageContent = use(messagePromise);
return <p>Here is the message: {messageContent}</p>;
}

Message は Suspense γ§γƒ©γƒƒγƒ—γ•γ‚Œγ¦γ„γ‚‹γŸγ‚γ€γƒ—γƒ­γƒŸγ‚ΉγŒθ§£ζ±Ίγ•γ‚Œγ‚‹γΎγ§γƒ•γ‚©γƒΌγƒ«γƒγƒƒγ‚―γŒθ‘¨η€Ίγ•γ‚ŒγΎγ™γ€‚γƒ—γƒ­γƒŸγ‚ΉγŒθ§£ζ±Ίγ•γ‚Œγ‚‹γ¨γ€γοΏ½?ε€€γŒ use γƒ•γƒƒγ‚―γ«γ‚ˆγ£γ¦θͺ­γΏε–γ‚‰γ‚Œγ€Message γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγŒγ‚΅γ‚Ήγƒšγƒ³γ‚Ήγƒ•γ‚©γƒΌγƒ«γƒγƒƒγ‚―γ‚’οΏ½?γζ›γˆγΎγ™γ€‚

"use client";

import { use, Suspense } from "react";

function Message({ messagePromise }) {
  const messageContent = use(messagePromise);
  return <p>Here is the message: {messageContent}</p>;
}

export function MessageContainer({ messagePromise }) {
  return (
    <Suspense fallback={<p>βŒ›Downloading message...</p>}>
      <Message messagePromise={messagePromise} />
    </Suspense>
  );
}

補袳

γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ«γƒ—γƒ­γƒŸγ‚Ήγ‚’ζΈ‘γ™ε ΄εˆγ€γοΏ½?θ§£ζ±Ίε€€γ―γ€γ‚΅γƒΌγƒγ¨γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆι–“γ§γ‚„γ‚Šγ¨γ‚Šε―θƒ½γ«γͺγ‚‹γ‚ˆγ†γ€γ‚·γƒͺをラむズ可能でγͺγ‘γ‚Œγ°γͺγ‚ŠγΎγ›γ‚“γ€‚ι–’ζ•°οΏ½?γ‚ˆγ†γͺγƒ‡γƒΌγ‚Ώεž‹γ―γ‚·γƒͺをラむズ可能ではγͺγ„γŸγ‚γ€γƒ—γƒ­γƒŸγ‚ΉοΏ½?θ§£ζ±Ίε€€γ¨γ—γ¦εˆ©η”¨γ§γγΎγ›γ‚“γ€‚

さらに深くηŸ₯γ‚‹

γƒ—γƒ­γƒŸγ‚Ήγ‚’γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§θ§£ζ±Ίγ™γ‚‹γ‹γ€γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§θ§£ζ±Ίγ™γ‚‹γ‹οΌŸ

γƒ—γƒ­γƒŸγ‚Ήγ―γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ«ζΈ‘γ—γ€use γƒ•γƒƒγ‚―γ‚’δ½Ώγ£γ¦γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§θ§£ζ±Ίγ™γ‚‹γ“γ¨γŒγ§γγΎγ™γ€‚γΎγŸγ€await γ‚’δ½Ώγ£γ¦γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆε΄γ§γƒ—γƒ­γƒŸγ‚Ήγ‚’θ§£ζ±Ίγ—γ€εΏ…θ¦γͺデータを props γ¨γ—γ¦γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ«ζΈ‘γ™γ“γ¨γ‚‚ε―θƒ½γ§γ—γ‚‡γ†γ€‚

export default function App() {
const messageContent = await fetchMessage();
return <Message messageContent={messageContent} />
}

γ—γ‹γ—γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ§ await を使用すると、await ζ–‡γŒη΅‚δΊ†γ™γ‚‹γΎγ§γοΏ½?γƒ¬γƒ³γƒ€γƒΌγŒγƒ–γƒ­γƒƒγ‚―γ•γ‚ŒγΎγ™γ€‚γ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‹γ‚‰γ‚―γƒ©γ‚€γ‚’γƒ³γƒˆγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ«γƒ—γƒ­γƒŸγ‚Ήγ‚’ζΈ‘γ™γ“γ¨γ§γ€γƒ—γƒ­γƒŸγ‚ΉγŒγ‚΅γƒΌγƒγ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?γƒ¬γƒ³γƒ€γƒΌγ‚’γƒ–γƒ­γƒƒγ‚―γ™γ‚‹γ“γ¨γ‚’ι˜²γγ“γ¨γŒγ§γγΎγ™γ€‚

ζ‹’ε¦γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚ΉοΏ½?ε–γ‚Šζ‰±γ„

ε ΄εˆγ«γ‚ˆγ£γ¦γ―γ€use γ«ζΈ‘γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚ΉγŒζ‹’ε¦γ•γ‚Œγ‚‹γ“γ¨γŒγ‚γ‚ŠγΎγ™γ€‚γƒ—γƒ­γƒŸγ‚ΉγŒζ‹’ε¦γ•γ‚ŒγŸε ΄εˆγ«γγ‚Œγ‚’ε‡¦η†γ™γ‚‹ζ–Ήζ³•γ―δ»₯δΈ‹οΏ½? 2 ぀です。

  1. エラーバウンダγƒͺを使ってユーアにエラーを葨瀺する
  2. Promise.catch で代替倀を提供する

落とし穴

use は try-catch ブロック内で呼び出すことはできません。try-catch γƒ–γƒ­γƒƒγ‚―γ‚’δ½Ώγ†δ»£γ‚γ‚Šγ«γ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’γ‚¨γƒ©γƒΌγƒγ‚¦γƒ³γƒ€γƒͺγ§γƒ©γƒƒγƒ—γ™γ‚‹γ‹γ€γΎγŸγ―γƒ—γƒ­γƒŸγ‚ΉοΏ½? .catch パソッドで代替倀を提供してください。

エラーバウンダγƒͺを使ってユーアにエラーを葨瀺する

γƒ—γƒ­γƒŸγ‚ΉγŒζ‹’ε¦γ•γ‚ŒγŸγ¨γγ«γƒ¦γƒΌγ‚Άγ«γ‚¨γƒ©γƒΌγ‚’θ‘¨η€Ίγ—γŸγ„ε ΄εˆγ―γ€γ‚¨γƒ©γƒΌγƒγ‚¦γƒ³γƒ€γƒͺ を使用できます。エラーバウンダγƒͺを使用するには、use γƒ•γƒƒγ‚―γ‚’ε‘Όγ³ε‡Ίγ—γ¦γ„γ‚‹γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’γ‚¨γƒ©γƒΌγƒγ‚¦γƒ³γƒ€γƒͺでラップします。use γ«ζΈ‘γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚ΉγŒζ‹’ε¦γ•γ‚Œγ‚‹γ¨γ€γ‚¨γƒ©γƒΌγƒγ‚¦γƒ³γƒ€γƒͺγ«ζ›Έγ‹γ‚ŒγŸγƒ•γ‚©γƒΌγƒ«γƒγƒƒγ‚―γŒθ‘¨η€Ίγ•γ‚ŒγΎγ™γ€‚

"use client";

import { use, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";

export function MessageContainer({ messagePromise }) {
  return (
    <ErrorBoundary fallback={<p>⚠️Something went wrong</p>}>
      <Suspense fallback={<p>βŒ›Downloading message...</p>}>
        <Message messagePromise={messagePromise} />
      </Suspense>
    </ErrorBoundary>
  );
}

function Message({ messagePromise }) {
  const content = use(messagePromise);
  return <p>Here is the message: {content}</p>;
}

Promise.catch で代替倀を提供する

use γ«ζΈ‘γ•γ‚ŒγŸγƒ—γƒ­γƒŸγ‚ΉγŒζ‹’ε¦γ•γ‚ŒγŸγ¨γγ«δ»£ζ›Ώε€€γ‚’ζδΎ›γ—γŸγ„ε ΄εˆγ€γƒ—γƒ­γƒŸγ‚ΉοΏ½? catch パソッドを使用できます。

import { Message } from './message.js';

export default function App() {
const messagePromise = new Promise((resolve, reject) => {
reject();
}).catch(() => {
return "no new message found.";
});

return (
<Suspense fallback={<p>waiting for message...</p>}>
<Message messagePromise={messagePromise} />
</Suspense>
);
}

γƒ—γƒ­γƒŸγ‚ΉοΏ½? catch γƒ‘γ‚½γƒƒγƒ‰γ‚’δ½Ώη”¨γ™γ‚‹γ«γ―γ€γƒ—γƒ­γƒŸγ‚Ήγ‚ͺγƒ–γ‚Έγ‚§γ‚―γƒˆοΏ½? catch を呼び出します。catch はエラーパッセージを引数とする閒数を唯一�?ι–’ζ•°γ¨γ—γ¦ε—γ‘ε–γ‚ŠγΎγ™γ€‚catch γ«ζΈ‘γ•γ‚ŒγŸι–’ζ•°γ«γ‚ˆγ£γ¦θΏ”γ•γ‚ŒγŸδ»»ζ„οΏ½?ε€€γŒγ€γƒ—γƒ­γƒŸγ‚ΉοΏ½?θ§£ζ±Ίε€€γ¨γ—γ¦δ½Ώη”¨γ•γ‚ŒγΎγ™γ€‚


γƒˆγƒ©γƒ–γƒ«γ‚·γƒ₯ーティング

β€œSuspense Exception: This is not a real error!”

あγͺたは React γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΎγŸγ―γƒ•γƒƒγ‚―ι–’ζ•°οΏ½?倖部で use γ‚’ε‘Όγ³ε‡Ίγ—γ¦γ„γ‚‹γ‹γ€γΎγŸγ― try-catch ブロック内で use を呼び出しています。try-catch ブロック内で use γ‚’ε‘Όγ³ε‡Ίγ—γ¦γ„γ‚‹ε ΄εˆγ―γ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγ‚’γ‚¨γƒ©γƒΌγƒγ‚¦γƒ³γƒ€γƒͺγ§γƒ©γƒƒγƒ—γ™γ‚‹γ‹γ€γƒ—γƒ­γƒŸγ‚ΉοΏ½? catch を呼び出してエラーをキャッチし、εˆ₯οΏ½?ε€€γ§γƒ—γƒ­γƒŸγ‚Ήγ‚’θ§£ζ±Ίγ—γΎγ™γ€‚γ“γ‘γ‚‰οΏ½?例を参照してください。

React γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΎγŸγ―γƒ•γƒƒγ‚―ι–’ζ•°οΏ½?倖部で use γ‚’ε‘Όγ³ε‡Ίγ—γ¦γ„γ‚‹ε ΄εˆγ―γ€use οΏ½?呼び出しを React γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΎγŸγ―γƒ•γƒƒγ‚―ι–’ζ•°γ«η§»ε‹•γ—γΎγ™γ€‚

function MessageComponent({messagePromise}) {
function download() {
// ❌ the function calling `use` is not a Component or Hook
const message = use(messagePromise);
// ...

上記�?ε ΄εˆγ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆοΏ½?クロージャ�?倖で use γ‚’ε‘Όγ³ε‡Ίγ™γ‚ˆγ†γ«γ™γ‚‹γ“γ¨γ§γ€γ‚³γƒ³γƒγƒΌγƒγƒ³γƒˆγΎγŸγ―γƒ•γƒƒγ‚―γ‹γ‚‰ use γ‚’ε‘Όγ³ε‡Ίγ™γ¨γ„γ†ζ‘δ»Άγ‚’ζΊ€γŸγ™γ‚ˆγ†γ«γͺγ‚ŠγΎγ™γ€‚

function MessageComponent({messagePromise}) {
// βœ… `use` is being called from a component.
const message = use(messagePromise);
// ...