序章

このチュートリアルでは、ReactフロントエンドJavascriptフレームワークとCSSグリッドを使用して、 Unsplash API を使用して写真画像を埋め込み、無限スクロール画像ギャラリーを構築します。 Scotch.iocodepenコーディングチャレンジをコードのベースとして使用し、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を使用するため、状態メソッドとライフサイクルメソッドをそれぞれuseStateuseEffectで処理します。

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コンポーネントを使用して各画像をレンダリングするために使用されます。

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グリッドを使用して画像ギャラリーを構築しました。 グリッドをいじって、さらに優れたセットアップを作成することができます。