を使うことで、子要素が読み込みを完了するまでフォールバックを表示させることができます。
<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
}