4
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.

【React】Material UIを用いてローディング画面を実装する

Posted at

背景

重いサイトを開く際には時間がかかること事があり、
ローディング画面をいったん挟むことがあります。
本記事ではWebサイトのローディング時に疑似的なローディング画面を作成する内容を紹介します。

作成するもの

animation.gif

環境

  • Vite:5.0.8
  • Typescript:5.2.2
  • @emotion/react:11.11.3
  • @emotion/styled:11.11.0
  • @mui/joy:5.0.0-beta.21

プロジェクトの作成

以下のコマンドでReact+TypeScriptのプロジェクトを作成します。

npm create vite@latest

MUIのインストール

Material UIのインストールします。

npm install @mui/joy @emotion/react @emotion/styled

ローディング中の画面

ローディング中のコンポーネントを作成しています。

Loading.tsx
import LinearProgress from '@mui/joy/LinearProgress';

function LoadingScreen() {
    return (
      <div className='LoadMain'>
        <div className='progressBarContainer'>
          <h2>Now Loading・・・</h2>
          <LinearProgress size="lg"/>
        </div>
      </div>
    )
}

export default LoadingScreen;

以下の部分でプログレスバーを作成しています。
sizeでバーの太さを調整(lg:太)しています。

<LinearProgress size="lg"/>

プログレスバーの詳細はドキュメントに記載されています。

以下のCSSでアニメーションを割り当てています。
animationプロパティに透明度が1から0に変化するfadeoutのキーフレームを当てています。

App.css
.LoadMain {
  height: 100vh;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: pink;
  animation: fadeout 6s;
}

@keyframes fadeout {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.progressBarContainer {
  text-align: center;
  width: 50%;
}

ローディング後の画面

ローディング後のコンポーネントを作成しています。

Loaded.tsx
function LoadedScreen() {
  return (
    <div className='LoadedMain'>
      <h1>ロード後の画面</h1>
    </div>
  )
}

export default LoadedScreen;

以下のCSSのanimationプロパティに、
透明度が0から1に変化するキーフレームのアニメーションを当てています。
これで徐々にローディング後の画面が表示されます。

App.css
.LoadedMain {
  height: 100vh;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: lightblue;
  animation: fadein 4s;
}

@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

Appコンポーネント

Appコンポーネントの全体は以下の通りです。
ローディングから5秒後にsetLoading(false)が呼び出され、
状態変数loadingtrueからfalseに更新されます。
三項演算子でloadingtrueの場合はLoadingScreen(ローディング中)を、
falseの場合はLoadedScreen(ローディング後)を返すようにします。

App.tsx
import { useEffect, useState } from 'react';

// 外部関数のインポート
import LoadingScreen from './Loading';
import LoadedScreen from './Loaded';

// 外部ファイルのインポート
import './App.css';

export default function App() {
  const [loading, setLoading] =useState(true);

  useEffect(() => {
      const timeoutId = setTimeout(() => {
        setLoading(false)
      }, 5000);

      return () => clearTimeout(timeoutId);
  }, []);

  return (
    <div >
      {loading ? (<LoadingScreen/>):(<LoadedScreen/>)}
    </div>
  );
}
main.tsx

main.tsxのコードは以下の通りです。

main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

実行結果

次のコマンドでプロジェクトを起動し、挙動を確認します。

npm run dev

画像のように疑似的なローディング画面を作成できました。

animation.gif

4
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
4
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?