Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8960

Reactでスケルトンスクリーンを実装してみた

$
0
0

はじめに

スケルトンスクリーンについて興味を持ったので、軽く実装してみました。
最先端のUIだから難しい?というイメージがありましたが、案外そうでもなかったです。

作ったもの:Web APIからユーザー一覧を表示する画面
完成:https://li8vx.csb.app/

スクリーンショット 2020-10-29 130207.png

こちらの例はReact+TypeScriptですが、別事例にも十分応用できると思います。

TL:DR

  1. HTML/CSSでスケルトン(?)を用意します。
  2. JSでAPIのローディング時にスケルトンを表示する実装を書きます。

HTML/CSS

ゼロから考えるのは面倒だったので既存コンポーネントを丸パクリしてCSSを解読しようとしました。
結果、思ったより単純でした。

コンポーネントライブラリはあの有名なMaterial-UIをを参考にしました。

https://material-ui.com/ja/api/skeleton/

このサンプルに当たっているCSSを開発者ツールで見てコピペしました。

高さはpropsで受け取れるようにしています。

Skelton.tsx
import*asReactfrom"react";import"./Skelton.css";exportfunctionSkelton({height}:{height:any}){return<divclassName="Skelton"style={{height:height}}></div>;
}
Skelton.css
.Skelton{/* root */display:block;background-color:rgba(0,0,0,0.1);/* transform */transform:scale(1,0.5);transform-origin:060%;/* box model */margin-top:0;margin-bottom:0;border-radius:4px;/* animation */animation:Skeleton1.5sease-in-out0.5sinfinite;}@keyframesSkeleton{0%{opacity:1;}50%{opacity:0.4;}100%{opacity:1;}}

JS

この処理のヒントも先ほどのMaterial-UIリンクをちょっと拝借させて頂きました。
APIはJSONPlaceholderを使っています。

またローディングの処理が分かるように一時停止する関数を使っています。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises
こちらの

constwait=ms=>newPromise(resolve=>setTimeout(resolve,ms));

この部分を参考にしました。

UserList.tsx
import*asReactfrom"react";import{Users}from"./types";import{Skelton}from"./Skelton";import{Box}from"./Box";constwait=(ms:number)=>newPromise((resolve)=>setTimeout(resolve,ms));typeUserListState={isLoaded:boolean;users:Users};exportclassUserListextendsReact.Component<{},UserListState>{constructor(props:Readonly<{}>){super(props);this.state={isLoaded:false,users:[]};}componentDidMount(){fetch("https://jsonplaceholder.typicode.com/users").then((response)=>response.json()).then((result)=>{wait(4000).then(()=>{constusers=result;this.setState({isLoaded:true,users:users});});});}render(){const{isLoaded,users}=this.state;return(<BoxoverflowY={!isLoaded?"hidden":"auto"}><ul>{(!isLoaded?Array.from(newArray(30)):users).map((user,i)=>(<liclassName="pb4"key={i}>{user?(<div><pclassName="font-bold">{user.username}</p>
<p>{user.email}</p>
</div>
):(<div><Skeltonheight={25}/>
<Skeltonheight={25}/>
</div>
)}</li>
))}</ul>
</Box>
);}}

おわりに

Material-UIに助けられました!


Viewing all articles
Browse latest Browse all 8960

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>