始めるチュートリアル開発者ガイドReactアップローダーの作成

imgixを使ったReactアップローダーの作成

Reactとimgixセッションエンドポイントを使用して、ユーザーがimgixアカウントに画像をアップロードできるインターフェースを構築します。このガイドでは、5GBまでの大容量ファイルのアップロードをサポートするために、アップロードセッションを使用します。

チュートリアルの完成したコードとデモは、このCodeSandboxにあります。

デモ

The Session Status is: No Status

前提条件

手順

手順1: Reactプロジェクトのセットアップ

まず、以下のコマンドを使用して新しいReactプロジェクトを作成します。

npx create-react-app imgix-uploader
cd imgix-uploader

次に、必要な依存関係をインストールします。

npm install axios react-imgix

srcディレクトリにReactUploader.jsという新しいコンポーネントを作成しましょう。このコンポーネントは、ファイルの選択からimgixへの送信まで、画像のアップロードプロセス全体を処理します。

インストールと設定が完了すると、ディレクトリは次のようになります(他のファイルも含まれる可能性があります)。

    • package.json

手順3: ReactUploader.jsコンポーネントの初期要素を作成する

まず、ReactUploader.jsコンポーネントにフォーム要素を作成しましょう。これらの要素は、画像をアップロードするためのユーザーインターフェースとなります。

また、必要な依存関係をインポートし、コンポーネントの初期状態を設定します。

作成するフォームには、imgix APIキーSource IDが必要です。

import { useState, useEffect } from "react"
import axios from "axios"
import Imgix from "react-imgix"
 
export default function ReactUploader() {
  return (
    <div>
      <form className="mb-4" onSubmit={handleSubmit}>
        {/* APIキー */}
        <input
          type="text"
          placeholder="Your imgix API key"
          value={apiKey}
          onChange={(e) => setApiKey(e.target.value)}
        />
        {/* Source ID */}
        <input
          type="text"
          placeholder="Source ID"
          value={sourceId}
          onChange={(e) => setSourceId(e.target.value)}
        />
        {/* imgixドメイン名 */}
        <input
          type="text"
          placeholder="your_subdomain.imgix.net"
          value={imgixDomain}
          onChange={(e) => setImgixDomain(e.target.value)}
        />
        {/* 画像をアップロードするパス */}
        <input
          type="text"
          placeholder="path/to/upload/to/"
          onBlur={(e) => {
            // アップロードパスを解析して末尾のスラッシュを削除します
            let parsedPath = ""
            if (uploadPath.charAt(0) !== "/" && uploadPath.length > 1) {
              parsedPath = "/" + uploadPath
            } else {
              parsedPath = uploadPath
            }
            if (uploadPath.charAt(uploadPath.length - 1) !== "/") {
              parsedPath += "/"
            }
            setUploadPath(parsedPath)
          }}
          value={uploadPath}
          onChange={(e) => setUploadPath(e.target.value)}
        />
        {/* 画像アップロード */}
        <input type="file" onChange={(e) => setImg(e.target.files[0])} />
        <button disabled={disableForm}>Upload Image</button>
      </form>
      {/* ステータス情報はここに表示されます */}
      <div>
        <h3>セッションのステータスは: {sessionStatus}</h3>
        <div>
          {sessionStatus === "ERROR" && <h3>{error}</h3>}
          {/* セッションが完了したら、imgix画像を表示します */}
          {sessionStatus === "COMPLETE" && (
            <Imgix
              src={imgixUrl}
              width={200}
              height={200}
              imgixParams={{ auto: "format,compress,enhance", fit: "crop" }}
            />
          )}
        </div>
        {sessionStatus === "COMPLETE" && <h4>{imgixUrl}</h4>}
      </div>
    </div>
  )
}

手順4: フォームハンドラーの実装

フォームが設定されたので、フォームの送信を処理し、画像をimgix APIに送信するロジックを実装しましょう。

Reactの状態管理

フォームデータとアップロードセッションのステータスを管理するために、Reactの状態管理を使用します。Reactの状態管理についての詳細は、Reactのドキュメントを参照してください。

export default function ReactUploader() {
  const [img, setImg] = useState()
  const [sessionStatus, setSessionStatus] = useState("No Status")
  const [imgixUrl, setImgixUrl] = useState()
  const [apiKey, setApiKey] = useState("")
  const [sourceId, setSourceId] = useState("")
  const [imgixDomain, setImgixDomain] = useState("")
  const [uploadPath, setUploadPath] = useState("")
  const [sessionId, setSessionId] = useState("")
  const [presignedUrl, setPresignedUrl] = useState("")
  const [error, setError] = useState("")
  const [disableForm, setDisableForm] = useState(false)
 
  return {
    /* 手順1のフォーム要素 */
  }
}

フォームハンドラー (handleSubmit)

フォームが送信されたときにhandleSubmit関数がトリガーされます。この関数はバリデーションを処理し、アップロードセッションを作成し、アップロードのためのデータを準備します。

export default function ReactUploader() {
  // 手順2と3のインポート文と状態変数
 
  // フォームの送信を処理する関数
  const handleSubmit = async (e) => {
    e.preventDefault()
 
    // エラーハンドリング
    if (!img) {
      alert("アップロードする画像を選択してください")
      return
    } else if (!apiKey) {
      alert("imgix APIキーを入力してください")
    } else if (!sourceId) {
      alert("ソースIDを入力してください")
    }
 
    setDisableForm(true)
    setSessionStatus("OPENING")
 
    //セッションを作成してセッションIDを設定
    await axios({
      method: "POST",
      url:
        `https://api.imgix.com/api/v1/sources/${sourceId}/upload-sessions/create` +
        uploadPath +
        img.name,
      maxBodyLength: Infinity,
      headers: {
        "Content-Type": "application/vnd.api+json",
        Authorization: `Bearer ${apiKey}`,
      },
    })
      .then((response) => {
        setSessionId(response.data.data.id)
        setSessionStatus(response.data.data.attributes.status)
        setPresignedUrl(response.data.data.attributes.url)
      })
      .catch((error) => {
        // サーバーエラーハンドリング
        console.log(error?.response?.data?.errors[0]?.detail)
        setSessionStatus("ERROR")
        setError(error?.response?.data?.errors[0]?.detail)
        console.log(error.message)
      })
  }
 
  return {
    /* 手順1のフォーム要素 */
  }
}
handleSubmitの主な手順

バリデーション: この関数は、画像、APIキー、およびソースIDが提供されているかどうかをチェックします。また、アップロードパスを解析します。これらが欠けている場合、ユーザーに警告し、実行を停止します。

フォームの無効化: フォームは無効化され(setDisableForm(true))、現在の送信が処理されている間、さらに送信できないようにします。

アップロードセッションの作成: ファイル名、ソースID、および画像を保存するパスを含むAPIリクエストがimgixに送信され、新しいアップロードセッションが作成されます。成功すると、セッションID、セッションステータス、および画像をアップロードするためのプリサインURLが保存されます。

手順5: useEffectを使用してアップロードプロセスを管理する

アップロードセッションが正常に作成されると、useEffectフックがsessionStatusを監視し、実際の画像アップロードを処理します。また、アップロードが完了したときやエラーが発生したときに状態を変更します。

export default function ReactUploader() {
 
  // 手順2と3のインポート文と状態変数
 
  useEffect(() => {
    //セッションIDから取得したプリサインURLを使用して画像をアップロードします
    // ドキュメント: https://docs.imgix.com/apis/management/assets#using-upload-sessions
    if (sessionStatus === "PENDING") {
      axios({
        method: "PUT",
        url: presignedUrl,
        headers: {
                  "Content-Type": "application/octet-stream",
                },
        data: img,
              }
            )
        .then(() => {
          // 画像がアップロードされたら、セッションを閉じて完了状態を設定します
          closeSession(sessionId)
          setSessionStatus("COMPLETE")
          setImgixUrl("https://" + imgixDomain + uploadPath + img.name)
          setDisableForm(false)
        })
        .catch((error) => {
          // エラーが発生した場合、エラーハンドラを設定します
          closeSession(sessionId)
          setSessionStatus("ERROR")
          console.log(error.message)
          setDisableForm(false)
        })
    }
 
    // エラーやアップロード時にセッションを閉じる関数
    const closeSession = (sessionId) => {
      // セッションを閉じます
      axios({
        method: "POST",
        url:
        `https://api.imgix.com/api/v1/sources/${sourceId}/upload-sessions/close/` +
        sessionId,
        headers: {
                  "Content-Type": "application/vnd.api+json",
                  Authorization: `Bearer ${apiKey}`,
                },
              }
      )
      .catch((error) => {
        console.log(error)
      })
    }
  }, [sessionStatus, error])
 
  // 手順4のhandleSubmit関数
 
  return (
    // 手順1のフォーム要素
 )
}

useEffectの主な手順

sessionStatusの監視: useEffectフックは、sessionStatusが変更されるたびに実行されます。ステータスが「PENDING」の場合、アップロードが進行します。

画像のアップロード: HTTP PUTリクエストがプリサインURLに送信され、選択された画像がアップロードされます。Content-Typeはバイナリデータをアップロードするため、application/octet-streamに設定されます。

成功またはエラーの処理: 成功時には、セッションが閉じられ、画像URLが保存されます。エラー時には、セッションが閉じられ、フォームが再び有効になります。

手順6: コンポーネントをアプリケーションに統合する

ReactUploaderコンポーネントが完成したので、メインアプリケーションに統合しましょう。src/App.jsを開き、以下の内容に置き換えます。

import React from "react"
import ReactUploader from "./ReactUploader"
 
function App() {
  return (
    <div className="App">
      <h1>imgixで画像をアップロード</h1>
      <ReactUploader />
    </div>
  )
}
 
export default App

手順7: アプリケーションを実行する

画像アップローダーを実際に動作させるために、ターミナルで次のコマンドを実行します。

npm start

これでアプリはhttp://localhost:3000で実行され、imgixに画像をアップロードできるようになります。

結論

このチュートリアルでは、imgix APIに画像をアップロードするシンプルなReactアプリケーションを作成しました。このアプリは、エラーハンドリングの強化、動的APIキー管理、より高度な画像処理など、追加機能を追加して拡張することができます。また、セッションの作成や画像のアップロードをサーバー側で処理することで、ユーザーのAPIキー入力を不要にすることもできます。

注: これは、APIキーとSource IDを入力する必要がある簡略化されたデモです。実際のアプリケーションでは、これらが既に指定されているはずです。

さらに、クライアント側で資格情報を扱うのは推奨されません。資格情報は悪意のあるアクターに露出する可能性があるためです。APIキーやその他の機密情報が安全に保存され、クライアントに露出しないようにしてください。APIキーを安全に扱う方法はいくつかあり、サーバーレス機能やバックエンドサーバーにリクエストを送信して、クライアント側からimgixにリクエストを送信する代わりに画像のアップロードを処理することが挙げられます。