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?

More than 1 year has passed since last update.

React18のsuspenseとreact-error-boundaryとTanStack Queryを使う @yukilulu0229

Last updated at Posted at 2024-02-13

を使うことで、子要素が読み込みを完了するまでフォールバックを表示させることができます。

<Suspense fallback={<Loading />}>
  <SomeComponent />
</Suspense>

参考 @nuko-suke

react-error-boundary

npm i react-error-boundary

使い方

準備

TanStack Queryと組み合わせる

npm i @tanstack/react-query

コード

main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      suspense: true,
    },
  },
})

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>,
)

const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      suspense: true,
    },
  },
})

new して変数に入れる

<QueryClientProvider client={queryClient}>
  <App />
</QueryClientProvider>
  • QueryClientProviderで囲む
  • client={queryClient}する
App.tsx
import {Suspense, useState} from "react";
import ReactQuery from "./components/ReactQuery.tsx";

function App() {
  return (
    <main style={{display: "flex", justifyContent: "center"}}>
      <div style={{flex: 1}}>
        <ErrorBoundary fallback={<p>エラーです</p>}>
          <Suspense fallback={<p>ローディング中</p>} >
            <ReactQuery />
          </Suspense>
        </ErrorBoundary>
      </div>
    </main>
  )
}

export default App

<Suspense fallback={<p>ローディング中</p>} >
  <ReactQuery />
</Suspense>

<Suspense fallback={<p>ローディング中</p>} >
で囲ってfallbackにロード中のコンポーネントを入れる

<ErrorBoundary fallback={<p>エラーです</p>}>

で囲ってエラーのときの処理をコンポーネントに入れる

ReactQuery.tsx
import React from 'react';
import AlbumList from "./AlbumList.tsx";
const ReactQuery = () => {
  return (
    <>
      <p>ReactQuery</p>
      <div style={{flexGrow: 1}}>
        <AlbumList />
      </div>
    </>
  );
};

export default ReactQuery;

AlbumList.tsx
import {useQuery} from "@tanstack/react-query";
import axios from "axios";
import React from 'react';

type Album = {
  userId: number,
  id: number,
  title: string
}


const fetchAlbums = async () => {
  const result = await axios.get<Album[]>("https://jsonplaceholder.typicode.com/albums");

  return result.data
}

const AlbumList = () => {
  const {data} = useQuery<Album[]> ({
    queryKey: ["album"],
    queryFn: fetchAlbums
  });

  return (
    <div style={{height: "300px", border: "2px solid gray", background: "cornsilk", overflowY: "scroll"}}>
      <p>AlbumList</p>
      {data && data.map((album) => <p key={album.id}>{album.id}:{album.title}</p>)}
    </div>
  );
};

export default AlbumList;

その他

SWRがvercelだが2024-02-13では

React はまだサスペンスをデータ取得フレームワークである SWR などで使うことを 推奨していません (詳細)。 これらの API は将来的に私たちの調査により変更される可能性があります。

となっている

読み込み時間をわざと遅らせる関数

App.tsx
const sleep = (ms: number):Promise<any> => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  })
}

const fetchAlbums = async () => {
  const result = await axios.get<Album[]>("https://jsonplaceholder.typicode.com/albums").then(await sleep(5000));

  return result.data
}
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?