ReactとCSSグリッドを使用して無限スクロール画像ギャラリーを構築する方法
序章
このチュートリアルでは、ReactフロントエンドJavascriptフレームワークとCSSグリッドを使用して、 Unsplash API を使用して写真画像を埋め込み、無限スクロール画像ギャラリーを構築します。 Scotch.ioのcodepenコーディングチャレンジをコードのベースとして使用し、React.jsを使用してインターフェースを構築し、Axiosを使用してHTTPリクエストを作成し、react-infinite-scroll
ライブラリを使用します無限スクロール機能を実装します。
また、このチュートリアルでは、Reactフックを使用し、プロジェクト全体で機能コンポーネントを使用します。
前提条件
このチュートリアルでは、この画像コラージュベースコードを、プロジェクトを構築するための開始点として使用します。
ステップ1—必要なパッケージのインストール
CDNから必要なすべての依存関係をインポートします。 Codepenには、モジュールの名前を入力し、結果から1つを選択してプロジェクトに追加できる、検索バーが用意されています。
インストールされる依存関係は次のとおりです。
Unsplash に進んでアプリケーションを作成し、アクセスキーを取得します。
ステップ2—ベースコンポーネントの構築
Reactでは、親コンポーネントのHTMLテンプレートはJSXで記述されています。 JSXでテンプレートを作成するこれらのHTML要素の記述に進みます。
機能コンポーネントを作成し、次のコマンドを使用してDOMでレンダリングします。
let Collage = () => {
// Return JSX
return (
<div className="hero is-fullheight is-bold is-info">
<div className="hero-body">
<div className="container">
<div className="header content">
<h2 className="subtitle is-6">Code Challenge #16</h2>
<h1 className="title is-1">
Infinite Scroll Unsplash Code Challenge
</h1>
</div>
// Images go here
</div>
</div>
</div>
);
};
// Render the component to the DOM element with ID of root
ReactDOM.render(<Collage />, document.getElementById("root"));
ここでは、親コンポーネントCollage
を作成し、JSXでHTML要素を返し、root
のIDでDOM要素にレンダリングしました。 Bulmaクラスは、ページの基本的なスタイルを提供するために使用されました。
ステップ3—単一の画像コンポーネントを構築する
次に、フェッチされた単一の画像に対して単一のコンポーネントを作成することに移りましょう。 これは、各画像の位置を設定するのに役立ちます。
次の機能を使用して単一の機能コンポーネントを作成します。
const UnsplashImage = ({ url, key }) => (
<div className="image-item" key={key} >
<img src={url} />
</div>
);
このコンポーネントは、url
およびkey
の小道具を受け取ります。これらは、表示される画像のURLであり、レンダリングされた各画像のキーです。 コンポーネントでは、<img/>
要素を使用して、フェッチされた画像を表示します。
ステップ4—Unsplashからのランダム画像のフェッチとレンダリング
Unsplashは、ランダムな画像をフェッチするための無料のAPIを提供します。 画像は状態コンテナに保存され、状態からDOMに渡されます。 React Hooksを使用するため、状態メソッドとライフサイクルメソッドをそれぞれuseState
とuseEffect
で処理します。
Collage
コンポーネントで、2つの状態変数を作成します。1つは着信画像を保持し、もう1つは画像が読み込まれるかどうかをプログラムに通知するブール値を格納します。
[...]
const [images, setImages] = React.useState([]);
const [loaded, setIsLoaded] = React.useState(false);
[...]
次に、Axiosを使用して10個のランダムな画像をフェッチする関数を作成します。 これは、取得したアクセスキーと返される画像の量を渡しながら、APIエンドポイントにGETリクエストを行うことで実行されます。 これを行う:
const fetchImages = (count = 10) => {
const apiRoot = "https://api.unsplash.com";
const accessKey = "{input access key here}";
axios
.get(`${apiRoot}/photos/random?client_id=${accessKey}&count=${count}`)
.then (res => {
setImages([...images, ...res.data]);
setIsLoaded(true);
});
};
AxiosはPromiseベースのライブラリであり、リクエストの解決時に、setImages
メソッドを使用して、フェッチされた画像を入力し、以前にフェッチされた画像を拡散します。 また、loaded
の値をtrue
に設定します。
画像が状態で保存されたので、コンポーネントがマウントされたら、このfetchImages
関数を呼び出しましょう。 以前のバージョンのReactでは、componentDidMount
ライフサイクルメソッドを使用してこれを実行していました。 ただし、Reactは、機能コンポーネントのすべてのライフサイクル操作を処理するためのuseEffect
フックを提供するようになりました。
Collage
コンポーネントで、マウント時にfetchImages
を呼び出します。
[...]
React.useEffect(() => {
fetchImages();
}, []);
[...]
useEffect
フックは、配列である2番目のパラメーターを取ります。 フックで提供される関数は、配列が更新または変更されるたびに実行されます。
これで、Unsplashから10個のランダムな画像をフェッチするページができました。 無限スクロールコンテナで画像をレンダリングすることに進みましょう。
React-infinite-scroll-componentは、読み込みスピナーまたは任意の要素をプレースホルダーとして表示し、ローダーが表示または表示に近づいたらさらにデータをフェッチする関数を呼び出し、指定されたデータを表示する機能を提供します。 返されたCollage
のJSXで、div
の後にheader
のクラスで、次のように無限スクロールコンポーネントの画像をレンダリングします。
<InfiniteScroll
dataLength={images}
next={() => fetchImages(5)}
hasMore={true}
loader={
<img
src="https://res.cloudinary.com/chuloo/image/upload/v1550093026/scotch-logo-gif_jq4tgr.gif"
alt="loading"
/>}
>
<div className="image-grid" style={{ marginTop: "30px" }}>
{loaded ?
images.map((image, index) => (
<UnsplashImage url={image.urls.regular} key={index} />
)): ""}
</div>
</InfiniteScroll>
InfiniteScroll
コンポーネントで、next
パラメーターに関数を渡しました。 この関数はfetchImages
関数を呼び出し、フェッチする画像の数である5
のパラメーターを渡します。 loader
パラメーターでは、読み込みプレースホルダーとして機能する画像をJSXに渡しました。
.map()
は、状態のimages
配列を反復処理し、UnsplashImage
コンポーネントを使用して各画像をレンダリングするために使用されます。
ステップ5—ギャラリーのスタイリング
CSSグリッドを使用して、フェッチした画像のスタイルを設定します。 CSSを次のように編集します。
.title {
font-family: 'Carter One';
}
.container {
margin-top: 50px;
text-align: center;
}
.image-grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: minmax(50px, auto);
.image-item:nth-child(5n){
grid-column-end: span 2;
}
img{
display: flex;
width: 100%;
height: 100%;
object-fit: cover;
}
}
これにより、幅250pxの列を持つグリッドが作成され、画像コンテナ全体が塗りつぶされます。 また、各画像に合わせて、行の最小値が50px、最大値がauto
になるように設定されています。 5つおきの画像でgrid-column-end
プロパティを使用して、1つではなく2つの画像スペースを使用するようにしました。
object-fit
プロパティは、各画像がそのコンテナのフルサイズに収まるか含まれていることを確認します。
完成したギャラリーはここhttps://codepen.io/Chuloo/full/BMPXqyにあります。
結論
このチュートリアルでは、ReactフックとCSSグリッドを使用して画像ギャラリーを構築しました。 グリッドをいじって、さらに優れたセットアップを作成することができます。