0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Svelte5でuseAsyncフックを作りたい

Last updated at Posted at 2025-01-24

結論

旧来のSvelteでは作りづらかったカスタムフック、Svelte5なら簡単に作れるようになったよ。例えばこんな感じ

useAsync.svelte.ts
export function useAsync<Fetcher extends (...args: any[]) => Promise<any>>(fetcher: Fetcher) {

  let data = $state<Awaited<ReturnType<Fetcher>> | null>(null);
  let error = $state<Error | null>(null);
  let isPending = $state(false);

  async function fetch(...args: Parameters<Fetcher>) {
    isPending = true;
    try {
      const result = await fetcher(...args);
      data = result;
      error = null;
    } catch (err) {
      error = err as Error | null;
      data = null;
    } finally {
      isPending = false;
    }
  }

  return {
    get data() {
      return data;
    },
    get error() {
      return error;
    },
    get isPending() {
      return isPending;
    },
    fetch,
  };
}

xxxx.svelte.ts ファイル内ではSvelte5で登場したRunesを使えるんだ。この関数のレスポンスそのものがリアクティブな値として返されるんだ。 応答を分割代入するとリアクティブ性が消えるから気をつけてね。(分割代入してもリアクティブ性を失いたくないなら、$derivedを介してやる必要がある)

usage
async function hoge() {
  return "something";
}

const asyncExecutor = useAsync(hoge);
asyncExecutor.exec()
// asyncExecutor.data, asyncExecutor.isPending, asyncExecutor.errorがリアクティブになる
// ただし分割代入して使いたいなら、そのままだとリアクティブ性を失うので、やりたければ下記のようにする必要がある
// let {data, isPending, error} = $derived(asyncExecutor);

補足

とはいえ、そもそもSvelteには最初からPromiseをテンプレートに描画するためのシンタックスがあるからuseAsyncやuseFetchを用意せずとも、概ね同じことを実現できるんだよね。使い勝手は好みによるところがあると思うから、どちらを使うかはそこ次第かな。

{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled or not a Promise -->
	<p>The value is {value}</p>
{:catch error}
	<!-- promise was rejected -->
	<p>Something went wrong: {error.message}</p>
{/await}

おまけ

Svelte5のカスタムフック集としてすごく参考になるページがあるから下記に掲載するね。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?