[React] Suspense(React 18 の新機能) を Axios と合わせてみる | 心を無にして始める React

Suspense

https://ja.reactjs.org/blog/2022/03/29/react-v18.html#new-suspense-features

サスペンスにより、コンポーネントツリーの一部がまだ表示できない場合に、ロード中という状態を宣言的に記述できるようになります。

いままで state で isLoading を準備して書いていたのを、楽にできる便利さん (。-`ω-)

準備

Axios をインストールして、json-server も立ち上げておきます。

これからのロード中

Suspense を使っていくので、コンポーネントがロード中になるときは Promise を throw するようにします。

コンポーネントが Promisethrow するっていう違和感はちょっとありますが、たぶん住めば都 (/・ω・)/

イメージ

画像は割愛 (。´・ω・)

一瞬だけ Spinner が出て、通信が終わったら Table がでます。

局所的なサンプル

throw axios.get('/cats').then(response => setState(response.data));
<Suspense fallback={<Spinner animation="border" variant="light" />}>
  <Pets values={cats} setState={setCats} />
</Suspense>

使ってみる

では、いつものように App.js を編集していきます。

import axios from 'axios';
import { Suspense, useState } from 'react';
import { Spinner } from 'react-bootstrap';

import './App.css';
import Table from './components/Table';

axios.defaults.headers.get['Content-Type'] = 'application/json';
axios.defaults.headers.get.Accept = 'application/json';
axios.defaults.baseURL = 'http://localhost:3000/';

const COLUMNS = ['id', 'name'];

const Pets = ({
  values,
  setState,
}) => {

  if (values === null) {
    if (setState) {
      throw axios.get('/cats').then(response => setState(response.data));
    }
  }

  return (
    <Table
      bordered
      hover
      striped
      variant="dark"
      columns={COLUMNS}
      rows={values.map(pet => [pet.id, pet.name])}
    />
  );
};

function App() {

  const [cats, setCats] = useState(null);

  return (
    <div className="App">
      <header className="App-header">
        <Suspense fallback={<Spinner animation="border" variant="light" />}>
          <Pets values={cats} setState={setCats} />
        </Suspense>
      </header>
    </div>
  );
}

export default App;

はい、できました。


ここにコードがないコンポーネントは、過去の記事にあります ('◇’)ゞ

Spinner は間違えて react bootstrap のをそのまま使っていますが、ご愛嬌ということで… (/ω\)