

 [適用於 JavaScript 的 AWS SDK V3 API 參考指南](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/)詳細說明 第 3 版 適用於 JavaScript 的 AWS SDK (V3) 的所有 API 操作。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# React Native 入門
<a name="getting-started-react-native"></a>

本教學課程說明如何使用 React Native [CLI 建立 React Native](https://reactnative.dev/docs/environment-setup) 應用程式。

![\[JavaScript code example that applies to React Native.\]](http://docs.aws.amazon.com/zh_tw/sdk-for-javascript/v3/developer-guide/images/browsericon.png)

**本教學課程顯示：**
+ 如何安裝和包含專案使用的適用於 JavaScript 的 AWS SDK 第 3 版 (V3) 模組。
+ 如何撰寫連線至 Amazon Simple Storage Service (Amazon S3) 的程式碼，以建立和刪除 Amazon S3 儲存貯體。

## 使用案例
<a name="getting-started-react-scenario"></a>

Amazon S3 是一種雲端服務，可讓您隨時從 Web 上的任何位置存放和擷取任意數量的資料。React Native 是一種開發架構，可讓您建立行動應用程式。本教學課程說明如何建立連線至 Amazon S3 的 React Native 應用程式，以建立和刪除 Amazon S3 儲存貯體。

應用程式使用下列適用於 JavaScript APIs AWS SDK：
+ [https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cognito-identity/](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cognito-identity/) 建構函數
+ [https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/s3/) 建構函數

## 先決條件任務
<a name="getting-started-react-setup"></a>

**注意**  
如果您已透過其他教學課程或現有組態完成下列任何步驟，請略過這些步驟。

本節提供完成此教學課程所需的最小設定。您不應將它視為完整的設定。針對該資訊，請參閱 [設定適用於 JavaScript 的 SDK](setting-up.md)。
+ 安裝下列工具：
  + [npm](https://docs.npmjs.com/getting-started/)
  + [Node.js](https://nodejs.org/en/download/)
  + [https://developer.apple.com/xcode/](https://developer.apple.com/xcode/) 如果您在 iOS 上測試
  + 如果您在 [Android 上測試 Android Studio](https://developer.android.com/studio/) 
+ 設定您的 [React Native 開發環境](https://reactnative.dev/docs/environment-setup)
+ 設定專案環境以執行這些 Node TypeScript 範例，並安裝適用於 JavaScript 和第三方模組的必要 AWS SDK。遵循[ GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/nodegetstarted/README.md) 上的指示。
+ 使用 AWS 服務進行開發 AWS 時，您必須建立程式碼與 進行身分驗證的方式。如需詳細資訊，請參閱[使用 進行 SDK 身分驗證 AWS](getting-your-credentials.md)。
**注意**  
此範例的 IAM 角色應設定為使用 **AmazonS3FullAccess** 許可。

## 步驟 1：建立 Amazon Cognito 身分集區
<a name="getting-started-react-create-identity-pool"></a>

在本練習中，您會建立並使用 Amazon Cognito Identity 集區，為 Amazon S3 服務提供未經驗證的應用程式存取權。建立身分集區也會建立兩個 AWS Identity and Access Management (IAM) 角色，一個用於支援身分提供者驗證的使用者，另一個用於支援未經驗證的訪客使用者。

在本範例中，我們只會使用未經驗證的使用者角色，以專注進行任務重點。您之後可以整合對身分提供者和已驗證使用者的支援。

**建立 Amazon Cognito 身分集區**

1. 登入 AWS 管理主控台 ，並在 Amazon Web Services 主控台開啟 Amazon Cognito [主控台](https://console.aws.amazon.com/cognito/)。

1. 在主控台開啟頁面上選擇**身分集區**。

1. 在下一頁中，選擇 **Create new identity pool (建立新的身分集區)**。
**注意**  
如果沒有其他身分集區，Amazon Cognito 主控台會略過此頁面並改為開啟下一頁。

1. 在**設定身分集區信任**中，選擇**訪客存取權**以進行使用者身分驗證。

1. 在**設定許可**中，選擇**建立新的 IAM 角色**，然後在 **IAM 角色**名稱中輸入名稱 （例如 *getStartedReactRole*)。

1. 在**設定屬性**中，在**身分集**區名稱中輸入名稱 （例如 *getStartedReactPool*)。

1. 在 **檢閱和建立** 中，確認您為新身分池所做的選擇。選取 **編輯** 以返回精靈並變更任何設定。當您完成時，請選取 **建立身分池**。

1. 請記下此新建立之身分集區的身分集區 ID 和 區域。您需要這些值來取代瀏覽器指令碼中的 *region* 和 *identityPoolId*。

建立 Amazon Cognito 身分集區後，您就可以新增 React Native 應用程式所需的 Amazon S3 許可。

## 步驟 2：將政策新增至已建立的 IAM 角色
<a name="getting-started-react-iam-role"></a>

若要啟用瀏覽器指令碼存取 Amazon S3 以建立和刪除 Amazon S3 儲存貯體，請使用為 Amazon Cognito 身分集區建立的未驗證 IAM 角色。這需要您將 IAM 政策新增至角色。如需 IAM 角色的詳細資訊，請參閱《*IAM 使用者指南*》中的[建立角色以將許可委派給 AWS 服務](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

**將 Amazon S3 政策新增至與未驗證使用者相關聯的 IAM 角色**

1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 開啟 IAM 主控台。

1. 在左側導覽窗格中，選擇 **Roles** (角色)。

1. 選擇您要修改的角色名稱 （例如 *getStartedRole*)，然後選擇**許可**索引標籤。

1. 選擇**新增許可**，然後選擇**連接政策**。

1. 在**新增此角色的許可**頁面中，尋找並選取 **AmazonS3ReadOnlyAccess** 的核取方塊。
**注意**  
您可以使用此程序來啟用對任何 AWS 服務的存取。

1. 選擇**新增許可**。

建立 Amazon Cognito 身分集區並將 Amazon S3 的許可新增至未經驗證使用者的 IAM 角色之後，您就可以建置應用程式。

## 步驟 3：使用 create-react-native-app 建立應用程式
<a name="react-prerequisites"></a>

執行下列命令來建立 React Native 應用程式。

```
npx react-native init ReactNativeApp --npm
```

## 步驟 4：安裝 Amazon S3 套件和其他相依性
<a name="getting-started-react-install-dependencies"></a>

在專案的 目錄中，執行下列命令來安裝 Amazon S3 套件。

```
npm install @aws-sdk/client-s3
```

此命令會在您的專案中安裝 Amazon S3 套件，並更新`package.json`以將 Amazon S3 列為專案相依性。您可以在 [https://www.npmjs.com/](https://www.npmjs.com/)npm 網站上搜尋 "@aws-sdk"，以找到此套件的相關資訊。

系統會在專案的 `node_modules` 子目錄中安裝這些套件及其相關聯的程式碼。

如需安裝 Node.js 套件的詳細資訊，請參閱 npm (Node.js 套件管理員） 網站上的[在本機下載和安裝](https://docs.npmjs.com/downloading-and-installing-packages-locally)套件和建立 Node.js 模組。 [https://docs.npmjs.com/creating-node-js-modules](https://docs.npmjs.com/creating-node-js-modules) [https://www.npmjs.com/](https://www.npmjs.com/)如需有關下載和安裝適用於 JavaScript 的 AWS SDK 的資訊，請參閱 [安裝適用於 JavaScript 的軟體開發套件](setting-up.md#installing-jssdk)。

安裝身分驗證所需的其他相依性。

```
npm install @aws-sdk/client-cognito-identity @aws-sdk/credential-provider-cognito-identity
```

## 步驟 5：撰寫 React Native 程式碼
<a name="getting-started-react-write-native-code"></a>

將下列程式碼新增至 `App.tsx`。將 *identityPoolId* 和*區域*取代為身分集區 ID 和建立 Amazon S3 儲存貯體的區域。

```
import React, { useCallback, useState } from "react";
import { Button, StyleSheet, Text, TextInput, View } from "react-native";
import "react-native-get-random-values";
import "react-native-url-polyfill/auto";

import {
  S3Client,
  CreateBucketCommand,
  DeleteBucketCommand,
} from "@aws-sdk/client-s3";
import { fromCognitoIdentityPool } from "@aws-sdk/credential-providers";

const client = new S3Client({
  // The AWS Region where the Amazon Simple Storage Service (Amazon S3) bucket will be created. Replace this with your Region.
  region: "us-east-1",
  credentials: fromCognitoIdentityPool({
    // Replace the value of 'identityPoolId' with the ID of an Amazon Cognito identity pool in your Amazon Cognito Region.
    identityPoolId: "us-east-1:edbe2c04-7f5d-469b-85e5-98096bd75492",
    // Replace the value of 'region' with your Amazon Cognito Region.
    clientConfig: { region: "us-east-1" },
  }),
});

enum MessageType {
  SUCCESS = 0,
  FAILURE = 1,
  EMPTY = 2,
}

const App = () => {
  const [bucketName, setBucketName] = useState("");
  const [msg, setMsg] = useState<{ message: string; type: MessageType }>({
    message: "",
    type: MessageType.EMPTY,
  });

  const createBucket = useCallback(async () => {
    setMsg({ message: "", type: MessageType.EMPTY });

    try {
      await client.send(new CreateBucketCommand({ Bucket: bucketName }));
      setMsg({
        message: `Bucket "${bucketName}" created.`,
        type: MessageType.SUCCESS,
      });
    } catch (e) {
      console.error(e);
      setMsg({
        message: e instanceof Error ? e.message : "Unknown error",
        type: MessageType.FAILURE,
      });
    }
  }, [bucketName]);

  const deleteBucket = useCallback(async () => {
    setMsg({ message: "", type: MessageType.EMPTY });

    try {
      await client.send(new DeleteBucketCommand({ Bucket: bucketName }));
      setMsg({
        message: `Bucket "${bucketName}" deleted.`,
        type: MessageType.SUCCESS,
      });
    } catch (e) {
      setMsg({
        message: e instanceof Error ? e.message : "Unknown error",
        type: MessageType.FAILURE,
      });
    }
  }, [bucketName]);

  return (
    <View style={styles.container}>
      {msg.type !== MessageType.EMPTY && (
        <Text
          style={
            msg.type === MessageType.SUCCESS
              ? styles.successText
              : styles.failureText
          }
        >
          {msg.message}
        </Text>
      )}
      <View>
        <TextInput
          onChangeText={(text) => setBucketName(text)}
          autoCapitalize={"none"}
          value={bucketName}
          placeholder={"Enter Bucket Name"}
        />
        <Button color="#68a0cf" title="Create Bucket" onPress={createBucket} />
        <Button color="#68a0cf" title="Delete Bucket" onPress={deleteBucket} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center",
  },
  successText: {
    color: "green",
  },
  failureText: {
    color: "red",
  },
});

export default App;
```

程式碼會先匯入所需的 React、React Native 和 AWS SDK 相依性。

在函數應用程式中：
+ 系統會建立 S3Client 物件，並使用先前建立的 Amazon Cognito 身分集區指定登入資料。
+ 方法 `createBucket`和 會分別`deleteBucket`建立和刪除指定的儲存貯體。
+ React Native View 會顯示文字輸入欄位，讓使用者指定 Amazon S3 儲存貯體名稱，以及建立和刪除指定 Amazon S3 儲存貯體的按鈕。

您可以在 [ GitHub 上取得](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/reactnative/ReactNativeApp/App.tsx)完整的 JavaScript 頁面。

## 步驟 6：執行範例
<a name="getting-started-react-native-run-sample"></a>

**注意**  
請記得登入！如果您使用 IAM Identity Center 進行身分驗證，請記得使用 AWS CLI `aws sso login`命令登入。

若要執行範例，請使用 npm `web`執行 `ios`、 或 `android`命令。

以下是在 macOS 上執行`ios`命令的範例輸出。

```
$ npm run ios

> ReactNativeApp@0.0.1 ios /Users/trivikr/workspace/ReactNativeApp
> react-native run-ios

info Found Xcode workspace "ReactNativeApp.xcworkspace"
info Launching iPhone 11 (iOS 14.2)
info Building (using "xcodebuild -workspace ReactNativeApp.xcworkspace -configuration Debug -scheme ReactNativeApp -destination id=706C1A97-FA38-407D-AD77-CB4FCA9134E9")
success Successfully built the app
info Installing "/Users/trivikr/Library/Developer/Xcode/DerivedData/ReactNativeApp-cfhmsyhptwflqqejyspdqgjestra/Build/Products/Debug-iphonesimulator/ReactNativeApp.app"
info Launching "org.reactjs.native.example.ReactNativeApp"

success Successfully launched the app on the simulator
```

以下是在 macOS 上執行`android`命令的範例輸出。

```
$ npm run android

> ReactNativeApp@0.0.1 android
> react-native run-android

info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 970 file(s) to forward-jetify. Using 12 workers...
info Starting JS server...
info Launching emulator...
info Successfully launched emulator.
info Installing the app...

> Task :app:stripDebugDebugSymbols UP-TO-DATE
Compatible side by side NDK version was not found.

> Task :app:installDebug
02:18:38 V/ddms: execute: running am get-config
02:18:38 V/ddms: execute 'am get-config' on 'emulator-5554' : EOF hit. Read: -1
02:18:38 V/ddms: execute: returning
Installing APK 'app-debug.apk' on 'Pixel_3a_API_30_x86(AVD) - 11' for app:debug
02:18:38 D/app-debug.apk: Uploading app-debug.apk onto device 'emulator-5554'
02:18:38 D/Device: Uploading file onto device 'emulator-5554'
02:18:38 D/ddms: Reading file permission of /Users/trivikr/workspace/ReactNativeApp/android/app/build/outputs/apk/debug/app-debug.apk as: rw-r--r--
02:18:40 V/ddms: execute: running pm install -r -t "/data/local/tmp/app-debug.apk"
02:18:41 V/ddms: execute 'pm install -r -t "/data/local/tmp/app-debug.apk"' on 'emulator-5554' : EOF hit. Read: -1
02:18:41 V/ddms: execute: returning
02:18:41 V/ddms: execute: running rm "/data/local/tmp/app-debug.apk"
02:18:41 V/ddms: execute 'rm "/data/local/tmp/app-debug.apk"' on 'emulator-5554' : EOF hit. Read: -1
02:18:41 V/ddms: execute: returning
Installed on 1 device.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 6s
27 actionable tasks: 2 executed, 25 up-to-date
info Connecting to the development server...
8081
info Starting the app on "emulator-5554"...
Starting: Intent { cmp=com.reactnativeapp/.MainActivity }
```

輸入您要建立或刪除的儲存貯體名稱，然後按一下**建立儲存貯體****或刪除儲存貯體**。相應的命令將傳送至 Amazon S3，並顯示成功或錯誤訊息。

![\[Bucket creation success message with options to create or delete a bucket.\]](http://docs.aws.amazon.com/zh_tw/sdk-for-javascript/v3/developer-guide/images/react-app-running.png)


## 可能的增強功能
<a name="getting-started-react-native-variations"></a>

以下是此應用程式的變化，您可以用來進一步探索在 React Native 應用程式中使用適用於 JavaScript 的 AWS SDK。
+ 新增按鈕以列出 Amazon S3 儲存貯體，並在列出的每個儲存貯體旁提供刪除按鈕。
+ 新增按鈕，將文字物件放入儲存貯體。
+ 整合 Facebook 或 Amazon 等外部身分提供者，以搭配已驗證的 IAM 角色使用。