UnsplashAPIを使用してReactで写真検索アプリを構築する方法
著者はCOVID-19救済基金を選択し、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
StackOverflow 2020 Developer Survey によると、Reactは最も人気のあるJavaScriptフレームワークの1つであり、ウェブアプリのビューを効率的に変更するなど、多くの理由があります。 Virtual DOM を使用して、再利用可能、構成可能、およびステートフルなコンポーネントを使用して、スケーラビリティなどを向上させます。 初心者のReact開発者は、実際のアプリケーションで使用するために知識を活用する経験を必要とすることがよくあります。 このチュートリアルでは、 Reactフックの使用方法、 useState()の使用方法、およびReactでAPI呼び出しを行う方法を紹介します。
この記事では、 UnsplashAPIを使用してReactで写真検索アプリケーションを構築する手順を説明します。 Unsplashは現在、最も使用され人気のある写真検索エンジンの1つであり、プロジェクトやアプリケーションを構築する際の優れたデータプロバイダーになる可能性があります。
このチュートリアルを終了すると、ReactHooksを使用してUnsplashAPIをクエリする実用的なアプリケーションができあがります。 このプロジェクトは、同じプログラミングロジックを再利用し、API呼び出しを含む他のプロジェクトを構築するためのベースとして使用できるため、定型文としても機能します。 写真検索アプリケーションには、次のように検索バーとレンダリングされた結果が含まれます。
完全なコードを確認したい場合は、 DigitalOceanCommunityGitHubリポジトリをご覧ください。
前提条件
このガイドに従うために:
- 無料のUnsplashアカウントが必要になります。このアカウントは、公式のUnsplashWebサイトで入手できます。
- Node.jsを実行する開発環境が必要になります。 このチュートリアルは、Node.jsバージョン10.20.1およびnpmバージョン6.14.4でテストされました。 これをmacOSまたはUbuntu18.04にインストールするには、Node.jsをインストールしてmacOSにローカル開発環境を作成する方法またはのPPAを使用したインストール]セクションの手順に従います。 Ubuntu18.04にNode.jsをインストールする方法。
- また、JavaScriptとHTMLの基本的な知識も必要です。これは、HTMLシリーズでWebサイトを構築する方法およびJavaScriptでコーディングする方法にあります。 CSSの基本的な知識も役立ちます。これは、 Mozilla DeveloperNetworkで見つけることができます。
ステップ1—空のプロジェクトを作成する
このステップでは、 Create React App を使用します。これにより、手動で構成することなく、最初のプロジェクトが実行されます。 プロジェクトディレクトリで、次のコマンドを実行します。
npx create-react-app react-photo-search
このコマンドは、react-photo-search
という名前のフォルダーを作成し、ReactWebアプリケーションが機能するために必要なすべてのファイルと構成を含めます。
cd
コマンドを使用してディレクトリを変更し、次のコマンドを実行してこのフォルダ内に移動します。
cd react-photo-search
次に、次のコマンドを実行して開発サーバーを起動します。
npm start
この開始スクリプトの詳細については、 Create ReactAppを使用してReactプロジェクトをセットアップする方法を確認してください。
次に、Webブラウザで http:// localhost:3000 に移動します。リモートサーバーからこれを実行している場合は、http://your_domain:3000
に移動します。
Reactテンプレートがあります:
先に進む前に、ファイルをクリーンアップする必要があります。 Create React Appには不要なサンプルコードが付属しており、コードの保守性を確保するためにプロジェクトをビルドする前に削除する必要があります。
npm start
によって既に使用されているため、別の端末を開く必要があります。
次のコマンドを実行して、index.css
のデフォルトのスタイルを削除します。
rm src/index.css
次に、次のコマンドを使用して、コードエディタでindex.js
を開きます。
nano src/index.js
index.css
を削除したので、index.js
からimport './index.css';
を削除します。
import ./index.css
を削除すると、index.js
はこれと同じようになります。
react-photo-search / src / index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister();
ファイルを保存して終了します。
次に、ターミナルで次のコマンドを実行して、Reactロゴを削除します。
rm src/logo.svg
次のコマンドでApp.css
を開きます。
nano src/App.css
App.css
からすべてを削除し、ファイルを保存して終了します。 これは、ステップ3で新しいスタイルで更新します。
次のコマンドでsrc/App.js
を開きます。
nano src/App.js
次のステップは、import logo from './logo.svg';
を削除し、App.js
ファイルのclassName="App"
を使用してdiv
からJSXを削除することです。 これにより、テンプレートのHTML要素が削除されます。
App.js
を次のように変更します。
react-photo-search / src / App.js
import React from 'react'; import './App.css'; function App() { return ( <div className="App"> </div> ); } export default App;
http://localhost:3000
は空白になります。
これで、Reactアプリが初期化され、そこからサンプルコードが削除されました。 次に、Unsplash Developerダッシュボードで新しいアプリケーションを作成し、作成したアプリケーションのAccess Key
とSecret Key
をコピーして、UnsplashAPIにアクセスします。
ステップ2—UnsplashAPIクレデンシャルを取得する
このセクションでは、Unsplash開発者アカウントを申請し、このプロジェクトの新しいアプリケーションを作成し、このアプリケーションのAccess Key
とSecret Key
をコピーしてUnsplashAPIにアクセスします。 Unsplash APIはパブリックAPIではないため、このプロジェクトには独自のUnsplashAPIキーのセットが必要になります。
Unsplash Developer Home にアクセスして、開発者として登録してください。 Unsplashアカウントをすでに作成しているので、これは簡単なプロセスになります。
[開発者のスプラッシュ解除]ページで、開発者として登録ボタンをクリックします。
登録するためにあなたの資格情報を記入してください。
開発者として登録すると、開発者ダッシュボードに自動的にリダイレクトされます。 新しいアプリケーションをクリックします。
APIの使用とガイドラインに同意するよう求められます。 チェックボックスをクリックしてから、同意するボタンをクリックして先に進みます。
次に、アプリケーション情報を入力するように求められます。 アプリケーションに適切な名前と説明を付けて、アプリケーションの作成をクリックします。
これでアプリケーションが作成され、キーセクションのAccess Key
とSecret Key
にアクセスできるようになりました。 これらのキーを安全な場所にコピーします。 コードの後半でそれらが必要になります。
アプリケーション名の後にDemoタグが表示されることに注意してください。
このタグは、アプリケーションが開発モードにあり、リクエストが1時間あたり50に制限されていることを意味します。 個人的なプロジェクトの場合、これで十分ですが、本番環境に申し込むこともできます。これにより、リクエストの制限が1時間あたり5000に増えます。 適用する前に、APIガイドラインに従うことを忘れないでください。
このセクションでは、Unsplash APIアプリケーションを作成し、このプロジェクトに必要なキーを取得しました。 このプロジェクトでは、公式の Unsplash JavaScript Library 、unsplash-js
を使用して、APIをアプリに統合します。 次のステップでは、unsplash.js
をインストールし、CSSを追加してプロジェクトのスタイルを設定します。
ステップ3—依存関係のインストールとCSSの追加
次に、unsplash-js
パッケージを依存関係としてインストールし、カスタムCSSを追加してプロジェクトのスタイルを設定します。 行き詰まった場合は、このプロジェクトのDigitalOceanコミュニティリポジトリを参照してください。
npmパッケージマネージャーを使用してunsplash-js
ライブラリをインストールするには、プロジェクトディレクトリで次のコマンドを実行します。
npm install unsplash-js
これは、このチュートリアルに従うためにインストールする必要がある唯一のライブラリです。 後で、 React-Bootstrap 、 Semantic UIReactなどのさまざまなReactユーザーインターフェイスライブラリを試すことができます。 このチュートリアルを実行した後、このプロジェクトを微調整してレイアウトを変更する場合は、これらのライブラリを追加する必要があります。
次に、Reactアプリのスタイルを設定します。 次のコマンドを実行して、App.css
を開きます。
nano src/App.css
このチュートリアルでは、CSSについて少しずつ説明します。
1つ目は、すべての要素を選択する*
セレクターです。 次のコードを追加します。
react-photo-search / src / App.css
* { box-sizing: border-box; background-color: rgb(244, 244, 244); color: #333; font-size: 10px; }
box-sizing
プロパティは、要素の幅と高さの合計の計算方法を設定します。この場合、要素の幅と高さの計算に境界線とパディングを使用するようにブラウザに指示します。 背景色はbackground-color
を使用して設定し、値はrgb(244, 244, 244)
で、背景に淡い白色を与えます。 color
は、要素のテキストの色を設定します。 ここでは、濃い灰色の色合いである16進コード#333
が使用されています。 font-size
はフォントのサイズを設定します。
次に、.App
ブロックを追加します。これにより、className="App"
の要素が選択されます。 デフォルトでは、親要素(className="App"
)にはある程度のマージンとパディングがあるため、次のコードは4辺すべてのmargin
とpadding
を0
に設定します。
react-photo-search / src / App.css
* { box-sizing: border-box; background-color: rgb(244, 244, 244); color: #333; font-size: 10px; } .App { margin: 0; padding: 0; }
次に、className="container"
を使用してdiv
要素にスタイルを追加します。 これは、div
とclassName="App"
の子要素です。 タイトル、フォーム、ボタン、画像を含むすべてがこのdiv
に含まれます。
react-photo-search / src / App.css
* { box-sizing: border-box; background-color: rgb(244, 244, 244); color: #333; font-size: 10px; } .App { margin: 0; padding: 0; } .container { margin: 0 auto; max-width: 1000px; padding: 40px; }
margin
プロパティは、要素の周囲のスペースを定義するために使用されます。 margin
は、top
、right
、bottom
、およびleft
に設定できます。 値を1つだけ追加すると、この1つの値がすべてのtop
、right
、bottom
、およびleft
に設定されます。 margin
に2つの値を加算すると、最初の値はtop
とbottom
に設定され、2番目の値はright
と[ X153X]。
margin: 0 auto;
によると、top
とbottom
には0
のマージンがあり、left
とright
にはauto
があります。 ]。 このauto
は、ブラウザがコンテナに基づいてマージンを設定することを意味します。 これを理解する例は、親要素が100px
で、子要素が50px
の場合、left
、およびright
のマージンは[ X163X] 。これにより、子要素が親要素の中央に配置されます。
max-width
は、要素のwidth
の最大値(この場合は1000px
)を設定します。 コンテンツが1000px
より大きい場合、要素のheight
プロパティはそれに応じて変更されます。そうでない場合、max-width
は効果がありません。
上記のように、margin
は要素の周囲のスペースを設定し、padding
は要素とそのコンテンツの間のスペースを設定します。 以前のコードは、container
div
とその中の要素の間に、4つの側面すべてから40px
のスペースがあることを意味します。
次に、アプリケーションのタイトルにスタイルを追加します。
react-photo-search / src / App.css
... .container { margin: 0 auto; max-width: 1000px; padding: 40px; } .title { font-size: 4.4rem; font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif; }
.title
は、アプリのタイトルである「ReactPhotoSearch」に対応します。 font-size
とfont-family
の2つのプロパティのみが設定されます。 ここで、rem
単位はfont-size
値に使用されます。 rem
値は、親要素に相対的なem
値とは異なり、ルートhtml
要素に相対的です。 ここで、4.4rem
は44px
(4.4 x 10)を意味します。 この10px
による乗算は、*
セレクターを使用してすべての要素のフォントサイズを10px
に設定したためです。 font-family
は要素のフォントを指定します。 フォールバックシステムとして機能するためにコードで渡される多くの値があります。 ブラウザが最初のフォントを提供しない場合は、次のフォントが設定されます。
次は.form
CSSブロックで、画像の検索に使用されるフォームが含まれています。 これには、入力検索フィールド、ボタン、およびラベルが含まれます。
react-photo-search / src / App.css
... .title { font-size: 4.4rem; font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif; } .form { display: grid; }
ここでは、display
プロパティのみが設定されています。 このプロパティは、要素の表示動作を指定します。 grid
、flex
、block
、inline
などのさまざまな値を取ることができます。 grid
は、要素をブロックレベルとして表示し、グリッドモデルに従ってコンテンツをレンダリングします。
次は.label
と.input
CSSブロックです。
react-photo-search / src / App.css
... .form { display: grid; } .label { font-size: 3rem; margin-bottom: 1rem; } .input { font-size: 1.6rem; padding: 0.5rem 2rem; line-height: 2.8rem; border-radius: 20px; background-color: white; margin-bottom: 1rem; }
font-size
、padding
、background-color
、margin-bottom
についてはすでに説明しましたので、line-height
とborder-radius
について説明します。 border-radius
は、要素の角の半径を定義します。 ここでは、値は20px
に設定されており、4辺すべてに使用されます。 border-radius
を50%
に設定すると、正方形の要素を楕円形にすることができます。 line-height
は線の高さを指定し、2.8rem
または28px
に設定されています。
次は.button
CSSブロックで、Searchボタンのスタイルを設定します。
react-photo-search / src / App.css
... .input { font-size: 1.6rem; padding: 0.5rem 2rem; line-height: 2.8rem; border-radius: 20px; background-color: white; margin-bottom: 1rem; } .button { background-color: rgba(0, 0, 0, 0.75); color: white; padding: 1rem 2rem; border: 1px solid rgba(0, 0, 0, 0.75); border-radius: 20px; font-size: 1.4rem; cursor: pointer; transition: background-color 250ms; }
background-color
、color
、padding
、border-radius
、およびfont-size
についてはすでに説明しました。 border
は、要素の境界線のスタイル、幅、および色を設定します。 ここで、border
は、border-width
、border-style
、およびborder-color
の省略形プロパティとして使用されます。 このコードは、検索ボタンの周りに1pxの黒一色の境界線を追加します。 cursor
は、要素の上を指すときのマウスカーソルを指定します。
次は、.button
で使用される:hover
セレクターです。
react-photo-search / src / App.css
... .button { background-color: rgba(0, 0, 0, 0.75); color: white; padding: 1rem 2rem; border: 1px solid rgba(0, 0, 0, 0.75); border-radius: 20px; font-size: 1.4rem; cursor: pointer; transition: background-color 250ms; } .button:hover { background-color: rgba(0, 0, 0, 0.85); }
これは、マウスを.button
要素に合わせると、背景色が変わることを意味します。
次のCSSブロックは.card-list
で、これはdiv
とclassName="card-list"
に対応します。 このdiv
は、その中のすべての画像を表示します。
react-photo-search / src / App.css
... .button:hover { background-color: rgba(0, 0, 0, 0.85); } .card-list { column-count: 3; }
column-count
は、要素内で渡される値に従って要素を列に分割します。 このコードは、card-list
div
を3つの列に分割し、画像はこれらの3つの列内に表示されます。
次は.card
と.card--image
CSSブロックです。 .card
は、内部に画像がある個々のdiv
を指し、.card--image
はこの画像のclassName
です。
react-photo-search / src / App.css
... .card-list { column-count: 3; } .card { margin-bottom: 1rem; display: flex; } .card--image { flex: 100%; margin-top: 1rem; border-radius: 10px; }
margin
、display
、およびborder-radius
についてはすでに説明しました。 .card
では、display
がflex
に設定されます。これは、要素がブロック要素のように動作し、フレックスボックスモデルに従って表示が設定されることを意味します。 ]。 省略形のプロパティflex:100%;
を使用して、flex-grow
、flex-shrink
、およびflex-basis
の値を設定します。 詳細については、Mozilla DeveloperNetworkでを読むことができます。
最後のCSSブロックには、メディアクエリが含まれます。 @media
ルールを使用すると、さまざまなメディアタイプ/デバイスにさまざまなスタイルを適用できます。
react-photo-search / src / App.css
... .card--image { flex: 100%; margin-top: 1rem; border-radius: 10px; } @media (min-width: 768px) { .form { grid-template-columns: auto 1fr auto; grid-gap: 1rem; align-items: center; } .input { margin-bottom: 0; } } @media only screen and (max-width: 600px) { .card-list { column-count: 1; } }
このコードによると、ブラウザウィンドウが600px
以下の場合、column-count
は3
から1
に変わります(ほとんどのモバイルデバイスに適用可能)。 これは、@media
ルールでmax-width
プロパティを使用しました。 その前のコードはmin-width
を使用しており、幅が768px
以上の場合、@media
ルール内の要素のスタイルを変更します。
grid-template-columns
は、グリッドモデルの列を指定するために使用されます。 列の数は、渡される値の数と同じであり、コード( auto 1fr auto
)によると3つです。 1番目と3番目のグリッド要素のサイズは、コンテナのサイズまたはコンテンツのサイズに応じて異なります。 2番目の要素には1fr
(フラクショナル単位)、つまり1番目と3番目の要素が占有された後に残ったスペースがサイズに応じて与えられます。 これらの3つの要素は、カメラの絵文字、検索入力フィールド、および検索ボタンになります。 絵文字とボタンがサイズに応じてスペースをとった後、残りの領域は検索入力フィールドに移動し、それに応じて幅が変更されます。
grid-gap: 1rem;
は、2つのグリッド線の間に1rem
のスペースを作成します。 align-items:center;
は、アイテムをコンテナの中央に配置します。
これで、アプリケーションのスタイリングが終了します。 保存してsrc/App.css
を終了します。 CSSファイル全体をまとめて表示したい場合は、このコードのGitHubリポジトリをご覧ください。
必要な依存関係をインストールし、プロジェクトのスタイル設定に必要なカスタムCSSを追加したので、次のセクションに進んで、プロジェクトのUIまたはレイアウトを設計できます。
ステップ4—ユーザーインターフェイスの設計
このセクションでは、プロジェクトのUIを設計します。 これには、見出し、ラベル、入力フィールド、ボタンなどの要素が含まれます。
次のコマンドでsrc/App.js
ファイルを開きます。
nano src/App.js
プロジェクトに見出しを追加するには、App.js
内にclassName="container"
を含むdiv
を作成します。 このdiv
の中に、h1
タグにclassName="title"
を追加し、タグの中にReact Photo Search
と書き込みます。 これがタイトルの見出しになります。
react-photo-search / src / App.js
import React from 'react'; import './App.css'; function App() { return ( <div className="App"> <div className="container"> <h1 className="title">React Photo Search</h1> </div> </div> ); }
ファイルを保存して終了します。 ブラウザに、アプリにタイトルが表示されます。
次に、ユーザーからの入力を受け取るフォームを作成します。 このフォームは、入力テキストフィールドと送信ボタンで構成されます。
このために、<SearchPhotos />
という名前の新しいコンポーネントを作成します。 別のコンポーネントを作成する必要はありませんが、このプロジェクトを開発するときに、コードをコンポーネントに分割すると、コードの記述と保守が容易になります。
src
フォルダーで、次のコマンドを使用してsearchPhotos.js
という名前の新しいファイルを作成して開きます。
nano src/searchPhotos.js
searchPhotos.js
内で、<SearchPhotos />
という名前の機能コンポーネントをエクスポートします。
react-photo-search / src / searchPhotos.js
import React from "react"; export default function SearchPhotos() { return ( <> </> ); }
これは、searchPhotos.js
ファイルに追加する必要のある機能コンポーネントの基本構造です。 このファイルを保存します。
次のステップは、App.js
のSearchPhotos
コンポーネントをインポートして使用することです。
新しいターミナルウィンドウで、App.js
を開きます。
nano src/App.js
次の強調表示された行をApp.js
に追加します。
react-photo-search / src / App.js
import React from "react"; import "./App.css"; import SearchPhotos from "./searchPhotos" function App() { return ( <div className="App"> <div className="container"> <h1 className="title">React Photo Search</h1> <SearchPhotos /> </div> </div> ); } export default App;
このファイルを保存します。
検索フォームを作成するには、form
タグを使用し、その中にinput
タグを使用して入力フィールドを作成し、button
タグを使用してボタンを作成します。
要素にそれぞれのタグのclassName
を付けます。 これを行っている間に、スタイリングのためにカメラの絵文字が入ったラベルを追加します。
react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() { return ( <> <form className="form"> <label className="label" htmlFor="query"> {" "} 📷 </label> <input type="text" name="query" className="input" placeholder={`Try "dog" or "apple"`} /> <button type="submit" className="button"> Search </button> </form> </> ); }
まず、className="form"
を使用してform
要素を作成し、その中にカメラの絵文字を使用してlabel
を作成しました。 次に、検索クエリが文字列になるため、属性type="text"
を持つinput
要素が表示されます。 name="query"
属性は、input
要素の名前を指定し、className="input"
は要素にスタイル設定のクラスを与え、検索バーのプレースホルダー値は[に設定されます。 X177X]。 form
の最後の要素は、type="submit"
を持つbutton
です。
ファイルを保存して終了します。 これで、アプリのタイトルの後に検索バーが表示されます。
アプリのUIが完成したので、最初にユーザーからの入力クエリを次のセクションに保存することで、機能の作業を開始できます。
ステップ5—検索クエリを使用して状態を設定する
このステップでは、状態と React Hooks について学び、それらを使用してユーザー入力を保存します。
アプリケーションの基本構造を構築したので、Reactの側面について説明します。 フォームはありますが、まだ何も実行されていないため、最初に行うことは、検索バーから入力を取得してアクセスすることです。 あなたは州でこれを行うことができます。
コアとなる状態は、コンポーネントのプロパティ値を格納するために使用されるオブジェクトです。 状態が変化するたびに、コンポーネントは再レンダリングされます。 このアプリでは、検索ボタンがクリックされるたびに検索バーからの入力またはクエリを保存する状態が必要です。
お気づきかもしれませんが、このプロジェクトでは機能コンポーネントを使用しています。 これにより、Reactフックを使用して状態を管理できます。 フックは、クラスを記述せずに状態を定義するなどのReact機能を使用する関数です。 このチュートリアルでは、useState()
フックを使用します。
最初に行うことは、searchPhotos.js
ファイル内にuseState
をインポートすることです。
ファイルを開きます。
nano src/searchPhotos.js
searchPhotos.js
ファイルの最初の行を次のように変更します。
react-photo-search / src / searchPhotos.js
import React, { useState } from "react"; export default function SearchPhotos() { ...
次に、useState()
を実装します。 これは、useState()
フックの構文です。
useState(initialState)
useState()
は、現在の状態と、一般にアップデーター関数として知られている関数を返します。 これらを保存するには、配列の破棄を使用できます。
const [query, setQuery] = useState(initialState);
この例では、query
はコンポーネントの現在の状態を格納し、setQuery
は状態を更新するために呼び出すことができる関数です。 initialState
は初期状態値を定義します。 用途に応じて、文字列、数値、配列、またはオブジェクトにすることができます。
プロジェクトでは、検索バーからの入力は文字列であるため、状態の初期値として空の文字列を使用します。
searchPhotos.js
ファイルに、次のコード行を追加します。
react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() { const [query, setQuery] = useState(""); return ( <> <form className="form"> <label className="label" htmlFor="query"> {" "} 📷 </label> ...
次のステップは、入力テキストフィールドのvalue
をquery
に設定し、それにonChange()
イベントを追加することです。 このonChange()
イベントには関数があり、その中でsetQuery()
を使用して状態を更新します。 入力文字列は、e.target.valueを使用して取得されます。
react-photo-search / src / searchPhotos.js
... <input type="text" name="query" className="input" placeholder={`Try "dog" or "apple"`} value={query} onChange={(e) => setQuery(e.target.value)} /> ...
これで、状態と入力フィールドの値が相互にリンクされ、この検索クエリを使用して画像を検索できます。
query
内の検索バーからの入力を、テスト目的でリアルタイムに表示できます。 状態を定義した場所の直後にconsole.log(query)
を追加します。
react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() { const [query, setQuery] = useState(""); console.log(query); return ( <> // </> ); }
ファイルを保存します。
これで、コンソール内に入力クエリを受け取ります。 ChromeのF12
またはFirefoxのCtrl+Shift+K
を使用して、コンソールを開くことができます。
これで、searchPhotos.js
は次のようになります。
react-photo-search / src / searchPhotos.js
import React, { useState } from "react"; export default function SearchPhotos() { const [query, setQuery] = useState(""); console.log(query); return ( <> <form className="form"> <label className="label" htmlFor="query"> {" "} 📷 </label> <input type="text" name="query" className="input" placeholder={`Try "dog" or "apple"`} value={query} onChange={(e) => setQuery(e.target.value)} /> <button type="submit" className="button"> Search </button> </form> </> ); }
このセクションでは、状態とReactフックについて説明し、ユーザー入力をquery
状態内のinput
フィールドに保存しました。 次のセクションでは、この検索クエリを使用して画像を検索し、応答を別の状態に保存します。
ステップ6—スプラッシュを解除するためのAPIリクエストを作成する
次に、unsplash-js
ライブラリを使用して、input
フィールドからのクエリを使用して画像を検索します。 応答は、pics
という名前の別の状態に保存されます。
unsplash-js
ライブラリはすでにインストールされているので、searchPhotos.js
ファイルにインポートします。 前のセクションからconsole.log()
ステートメントを削除することもできます。
react-photo-search / src / searchPhotos.js
import React, { useState } from "react"; import Unsplash, { toJson } from "unsplash-js"; ...
toJson
は、unsplash-js
ライブラリのヘルパー関数であり、応答をJSON形式に変換するために使用されます。 ヘルパー関数の詳細については、unsplash-jsGitHubページをご覧ください。
アプリでUnsplashを使用するには、次のようにnew
キーワードを使用してインスタンスを作成します。
react-photo-search / src / searchPhotos.js
import React, { useState } from "react"; import Unsplash, { toJson } from "unsplash-js"; const unsplash = new Unsplash({ accessKey: "your_Access_Key", });
Unsplash Access Key
を貼り付けて、your_Access_Key
を置き換えます。これで、APIリクエストを行うことができます。
警告:APIまたはサービスのアクセスキーまたはクライアントIDを共有しないでください。 潜在的な悪意のある人物は、インターネット上でそれらを悪用する可能性があります。 このシナリオでは、サービスプロバイダーによってスパムとしてフラグが立てられる可能性のある異常な量の要求を行う可能性があり、これによりアプリケーションとアカウントが非アクティブ化される可能性があります。
次に、検索ボタンをクリックするとトリガーされる非同期関数を作成します。
query
の状態を定義した直後に、async
関数を定義します。
react-photo-search / src / searchPhotos.js
... export default function SearchPhotos() { const [query, setQuery] = useState(""); const searchPhotos = async (e) => { e.preventDefault(); console.log("Submitting the Form") };
ここで、e.preventDefault()
は、検索ボタンがクリックされるたびにページの再読み込みを停止します。 この関数は、form
タグ内のonSubmit
イベントで渡すことができます。 これについて詳しくは、公式Reactドキュメントをご覧ください。
react-photo-search / src / searchPhotos.js
... return ( <> <form className="form" onSubmit={searchPhotos}> ...
ファイルを保存します。 ここで、検索ボタンをクリックすると、コンソールにSubmitting the Form
が表示されます。 コンソールで正常に応答した後、このconsole.log()
を削除できます。
searchPhotos()
関数内では、Unsplashインスタンス(unsplash
)を使用します。 search
方式で画像を検索できます。 そのための構文は次のとおりです。
search.photos(keyword, page, per_page, filters)
画像を検索するためのコードは次のとおりです。 searchPhotos()
関数内に次のコードを追加します。
react-photo-search / src / searchPhotos.js
... const searchPhotos = async (e) => { e.preventDefault(); unsplash.search .photos(query) .then(toJson) .then((json) => { console.log(json); }); }; ...
まず、unsplash.search
を使用してから、検索対象(この場合はphotos
)を指定します。 users
またはcollections
を検索することもできます。 photos
は、検索するキーワードとして最初に必要な引数を取ります。これはquery
です。 オプションの引数を使用して、ページ、ページごとの応答、画像の向きなどを指定することもできます。 このチュートリアルでは、page
およびper_page
引数のみが必要であり、Unsplashから取得する応答項目を制限します。
photos
で提供できるすべての引数は次のとおりです。
口論 | タイプ | オプション/必須 | デフォルト |
---|---|---|---|
keyword
|
ストリング | 必須 | |
page
|
番号 | オプション | |
per_page
|
番号 | オプション | 10 |
filters
|
物体 | オプション | |
filters.orientation
|
ストリング | オプション | |
filters.collections
|
配列 | オプション |
詳細については、unsplash-jsGitHubページをご覧ください。
toJson
メソッドを使用して応答をJSONに変換し、最後にconsole.log()
応答を使用して、API要求がエラーなしで行われたことをテストします。 次の手順で、このconsole .log ()
を削除します。
ファイルを保存します。 次に、コンソールを開き、検索ボタンをクリックします。 次のような応答JSONが見つかります。
{ "results": [{ "description": "Pink Wall Full of Dogs", "alt_description": "litter of dogs fall in line beside wall", "urls": { "raw": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjE0MTQxN30", "full": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0MTQxN30", "regular": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=1080&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30", "small": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30", "thumb": "https://images.unsplash.com/photo-1529472119196-cb724127a98e?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE0MTQxN30" }, ... }
Unsplash APIから正常な応答が見つかったら、console.log()
ステートメントを削除またはコメント化できます。これは、コードが正常に機能していることを意味します。 このアプリは"urls"
フィールドが画像のソースになるためです。
unsplash-js
ライブラリを使用して検索ボタンがクリックされたときに、ユーザーからのクエリを使用して画像を検索しました。 次に、応答をpics
という名前の別の状態に保存し、この状態内の要素をマッピングして画像を表示します。
ステップ7—Webページに画像を表示する
この最後のセクションでは、Unsplash APIからの応答をpics
という名前の別の状態に保存し、この状態の要素にマップしてWebページに画像を表示します。
画像を表示するには、応答JSONにアクセスする必要があります。そのためには、別の状態が必要になります。 以前の状態query
には、UnsplashAPIへのリクエストを行うために使用されたユーザーからのクエリが保存されていました。 この状態pics
には、UnsplashAPIから取得した画像応答が保存されます。
searchPhotos.js
で、次のような別の状態を定義します。
react-photo-search / src / searchPhotos.js
... const [query, setQuery] = useState(""); const [pics, setPics] = useState([]); ...
この状態は空のarrayで初期化されており、すべての応答はこの状態内のオブジェクトとして保存されます。 つまり、これはオブジェクトの配列です。
この状態をJSONで更新するには、unsplash
APIリクエスト内でsetPics
を使用します。
react-photo-search / src / searchPhotos.js
... unsplash.search .photos(query, 1, 20) .then(toJson) .then((json) => { setPics(json.results); }); ...
これで、新しいクエリを検索するたびに、この状態がそれに応じて更新されます。
次に、form
タグが終了する直後にclassName="card-list"
を使用してdiv
を作成します。
react-photo-search / src / searchPhotos.js
... <button type="submit" className="button"> Search </button> </form> <div className="card-list"> </div> </> ); }
このdiv
内で、状態をマッピングし、画像のid
を表示します。
react-photo-search / src / searchPhotos.js
... <button type="submit" className="button"> Search </button> </form> <div className="card-list"> {pics.map((pic) => pic.id )} </div> </> ); }
最初に{}
を使用してJavaScript式を渡し、その中で .map()メソッドを州で使用します。
ファイルを保存します。 ここで検索すると、Webページ上のさまざまなオブジェクトに関連付けられているid
が表示されます。
これは厄介ですが、これはアプリケーションが機能していることも意味します。
pic.id
を表示する代わりに、map
関数内でJSXを開き、className="card"
を使用して新しいdiv
を作成します。 これは、個々の画像のコンテナになります。
react-photo-search / src / searchPhotos.js
... <button type="submit" className="button"> Search </button> </form> <div className="card-list"> { pics.map((pic) => <div className="card"></div>); } </div> </> ); }
これで、このdiv
内に画像を表示できます。
react-photo-search / src / searchPhotos.js
... <button type="submit" className="button"> Search </button> </form> <div className="card-list"> { pics.map((pic) => <div className="card"> <img className="card--image" alt={pic.alt_description} src={pic.urls.full} width="50%" height="50%" ></img> </div>); } </div> </> ); }
戻って応答JSONを見ると、別の種類の情報が見つかります。 "urls"
には画像へのパスが含まれているため、ここでpic.urls.full
は画像への実際のパスであり、pic.alt_description
は画像の代替説明です。
"urls"
内には、次のようなさまざまなデータを提供するさまざまなフィールドがあります。
raw
:ユーザーが撮影した実際のRAW画像。 full
:.jpg
形式のRaw画像。 regular
:実用に最適、width=1080px
。 small
:低速のインターネット速度に最適です。width=400px
。 thumb
:画像のサムネイルバージョンwidth=200px
。
このチュートリアルでは、full
を使用していますが、他のタイプを試すこともできます。 また、デフォルトのheight
およびwidth
を画像に指定しました。
ファイルを保存します。
アプリケーションはほぼ完成しています。 今すぐ検索すると、アプリケーションの動作を確認できます。 しかし、まだ小さなコード行が残っています。 画像を検索してブラウザでコンソールに移動すると、警告が表示されます。
Web consoleWarning: Each child in a list should have a unique "key" prop.
これを修正するには、画像のid
を使用して、すべての子に一意のkey
を渡します。 このkey
prop は、リスト内の各子のIDをReactに明示的に通知します。 これにより、子がレンダリング間で状態を失うのを防ぐこともできます。
react-photo-search / src / searchPhotos.js
... <div className="card-list"> {pics.map((pic) => <div className="card" key={pic.id}> <img className="card--image" alt={pic.alt_description} src={pic.urls.full} width="50%" height="50%" ></img> </div>)}; </div> </> ); }
unsplash.search.photos()
に対応する引数を渡すことで、表示する画像の数を調整できます。
ファイルを保存して終了します。 これで、写真検索アプリが機能するようになります。
このセクションでは、Unsplash APIからの応答をpics
状態に保存し、pics
の要素にマッピングして画像を表示しました。
結論
このチュートリアルでは、UnsplashAPIを使用してReactPhotoSearchアプリを開発しました。 プロジェクトを構築する際に、チュートリアルでは、React Hooksの使用方法、APIのクエリ方法、およびユーザーインターフェイスのスタイル設定方法について説明しました。
このアプリケーションを拡張するためにできることはたくさんあります。 たとえば、ランダムボタンを追加してランダムな画像を表示したり、チェックボックスを作成して写真の検索とユーザーの好みに応じて写真を投稿したユーザーを切り替えたり、無限スクロールを追加したりできます。 ]より多くの画像などを表示します。 同じコンセプトを使用して、 Hacker NewsAPIなどのAPIリクエストを含む他のプロジェクトを作成することもできます。
Reactチュートリアルをもっと見たい場合は、Reactトピックページをチェックしてください。