やりたいこと
- ランダムな画像URLを返すAPIから,取得した画像を表示するWEBアプリケーション.
- ボタンを押すと画像が切り替わる(再度API)
- 画像の切り替わりには時間がかかる
- APIからのフェッチ処理, URLへのアクセス,画像の描画などが原因
➡️ 画像の切り替わり中にはローディングのアニメーション(ローダー)を表示したい
- APIからのフェッチ処理, URLへのアクセス,画像の描画などが原因
実装方法
大きく2つ考えられる.
1. 画像が表示される瞬間に表示コンテンツを切り替え(ローダー↔️猫画像)
- Loadingバーの様な,時間経過が目に見えるコンテンツをローダーとして使用したい場合など.
2. 画像の背景で常にローダーを動かす
- シンプルなローダーの場合,こちらの方が楽に実装できて良いかも...
正直,2の方法のほうが楽だと思います.1の方法は似たようなケースが見つからず大変だった(今回は1の形で実装したかったので,がんばって実装しました)
使用技術
- フロントエンド
- html
- css (css module)
- React
- Next.js
- バックエンド
- The Cat API
- ランダムな猫の画像データをjson形式で返すウェブAPI
- 画像はURLで渡されるため,img src="https://〇〇" の形式に.
- APIからjsonの取得に加え,imgタグに読み込んだ"https://〇〇" へのアクセス時間もタイムラグが生じる
- The Cat API
結論
以下は,この機能の実装にあたっての重要部分です.(コード全体は以下のURLから)
https://github.com/shimiharu1012/random-cat
// 画像の描写が完了したら呼び出される
// loadingを更新する
//その後,再レンダリング
const handleLoad=()=>{
setLoading(false)
}
// !!!!!重要!!!!!
// loadingはreactのstate
// loadingの真偽で分岐し,要素を隠す場合はstyle.hiddenを代入
// もう一方には空文字列を代入
const isVisibleLoader=loading ? "" : styles.hidden
const isVisibleImage=loading ? styles.hidden : ""
return(
<div className={styles.container}>
<button onClick={handleClick} className={styles.toNext}>他のニャンコも見る</button>
<div className={styles.imageContainer}>
<div className={`${styles.loader} ${isVisibleLoader}`}></div>
// 画像が完全に描画されたらイベントonLoadの関数handleLoadが実行される
<img onLoad={handleLoad} className={`${styles.image} ${isVisibleImage}`} src={ImageUrl}></img>
</div>
</div>
)
index.module.css
.hidden{
display: none;
}
以下が参考になりました
実際の動作はこんな感じ
コード全体
https://github.com/shimiharu1012/random-cat
感想
珍しいパターンを実装してみることは大事かも.いい勉強になる.
ただ,実務などでは,その実装は本当に必要か?という点を考慮する必要があるだろう.
今回の場合なら,ローダーを画像の後ろで常に待機させておけば十分だし,それでもアニメーションに違和感があるなら,ローダーの種類を変えてみたりして違和感を少なくするという解決策もある.
参考