今回は、クライアント側で処理中などをユーザにわかるようにするためのローディング画面(ぐるぐる回るアイコンなど)を表示する実装方法の例を紹介していきます。
ローディング画面を表示するための状態を管理するライブラリに「Recoil」を使用しています。
検証環境
検証に使用した環境/ライブラリを次に記載します。
- React
- バージョン:18.2.0
- Next.js
- バージョン:12.1.6
- Recoil
- バージョン:0.7.4
動作例
ローディング画面を表示する動作例は、次のサイトで確認することができます。
プロジェクト情報
実装例で紹介しているプログラム内容などの詳細については、次のサイトで確認することができます。
プログラム内容
ローディングコンポーネント
【src/components/loading.tsx】
ローディング処理に関するコンポーネントの全体ソースコードは、次のようになります。
import { atom } from "recoil";
import { useRecoilState, useRecoilValue } from "recoil";
type LoadingTyep = {
loading: boolean;
};
const loadingState = atom<LoadingTyep>({
key: "loadingState",
default: {
loading: false
}
});
export const useLoading = () => {
const [state, setState] = useRecoilState<LoadingTyep>(loadingState);
const start = () => {
setState({ ...state, ...{ loading: true } });
};
const stop = () => {
setState({ ...state, ...{ loading: false } });
};
return { start, stop };
};
export const Loading = () => {
const state = useRecoilValue<LoadingTyep>(loadingState);
if (!state.loading) {
return <></>;
}
return (
<div>
<img src="images/loading.gif" alt="loading" />
<div>Loding...</div>
</div>
);
};
export default Loading;
ローディングの状態を管理するための定義は、次の箇所になります。
type LoadingTyep = {
loading: boolean;
};
const loadingState = atom<LoadingTyep>({
key: "loadingState",
default: {
loading: false
}
});
表示状態は、boolean
型のloading
という名前で管理しています。
ローディングの状態を変更するための処理は、次の箇所になります。
export const useLoading = () => {
const [state, setState] = useRecoilState<LoadingTyep>(loadingState);
const start = () => {
setState({ ...state, ...{ loading: true } });
};
const stop = () => {
setState({ ...state, ...{ loading: false } });
};
return { start, stop };
};
start
関数は、ローディング表示を開始状態に変更しています。stop
関数は、ローディング表示を終了状態に変更しています。
ローディングの表示をするための処理は、次の箇所になります。
export const Loading = () => {
const state = useRecoilValue<LoadingTyep>(loadingState);
if (!state.loading) {
return <></>;
}
return (
<div>
<img src="images/loading.gif" alt="loading" />
<div>Loding...</div>
</div>
);
};
export default Loading;
表示状態を取得するための処理は、const state = useRecoilValue<LoadingTyep>(loadingState)
の箇所になります。
state.loading
を使用してローディングの表示有無の判定をしています。ローディング表示は、任意の表示処理に変更することもできます。実装例では、画像を表示する処理になっています。
APPコンポーネント
【src/pages/_app.tsx】
APPコンポーネントの全体ソースコードは、次のようになります。
import type { AppProps } from "next/app";
import { RecoilRoot } from "recoil";
import Loading from "../components/loading";
function App({ Component, pageProps }: AppProps) {
return (
<>
<RecoilRoot>
<div>Next.js + TypeScript + Recoil</div>
<div>Loading Example.</div>
<Loading />
<Component {...pageProps} />
</RecoilRoot>
</>
);
}
export default App;
Recoil
を使用するためRecoilRoot
タグで全体を括る必要があります。ローディング表示するためLoading
コンポーネントも指定しています。
画面表示
【src/pages/index.tsx】
画面を表示するための全体のソースコードは、次のようになります。
import type { NextPage } from "next";
import { useLoading } from "../components/loading";
const Index: NextPage = () => {
const { start, stop } = useLoading();
return (
<div>
<div>
<button type="button" onClick={start}>
<span>Start</span>
</button>
<button type="button" onClick={stop}>
<span>Stop</span>
</button>
</div>
</div>
);
};
export default Index;
ローディングの状態を変更するための関数の取得処理は、const { start, stop } = useLoading()
の箇所になります。ローディングコンポーネントのstart
関数とstop
関数を使用できるようになります。
実装例では、ボタン押下のonClick
イベントのタイミングでローディング表示の状態を変更することにより、表示制御をしている処理になります。
まとめ
Recoil
を使用したローディング表示をするための実装例を紹介しました。