

 [适用于 JavaScript 的 AWS SDK V3 API 参考指南](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/)详细描述了 适用于 JavaScript 的 AWS SDK 版本 3 (V3) 的所有 API 操作。

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

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

本教程将向您展示如何使用 [React Native CLI](https://reactnative.dev/docs/environment-setup) 创建 React Native 应用程序。

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

**本教程将向您展示：**
+ 如何安装和包含项目使用的 JavaScript 版本 3 (V3) 模块的 AWS SDK。
+ 如何编写代码连接到 Amazon Simple Storage Service（Amazon S3），以创建和删除 Amazon S3 存储桶。

## 情景
<a name="getting-started-react-scenario"></a>

Amazon S3 是一项云服务，让您可以随时在 Web 上的任何位置存储和检索任意数量的数据。React Native 是一个开发框架，可用于创建移动应用程序。本教程展示了如何创建一个 React Native 应用程序，以连接到 Amazon S3 来创建和删除 Amazon S3 存储桶。

该应用程序使用以下 AWS SDK 用于 JavaScript APIs：
+ [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>

**注意**  
如果已通过其他教程或现有配置完成以下任意步骤，请跳过这些步骤。

本节介绍完成本教程所需的最低设置。您不应将此视为完整设置。为此，请参阅[将 SDK 设置为 JavaScript](setting-up.md)。
+ 安装以下工具：
  + [npm](https://docs.npmjs.com/getting-started/)
  + [Node.js](https://nodejs.org/en/download/)
  + [Xcode](https://developer.apple.com/xcode/)（如果您在 iOS 上测试）
  + [Android Studio](https://developer.android.com/studio/)（如果您在 Android 上测试）
+ 设置 [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 角色应设置为使用 **AmazonS3 FullAccess** 权限。

## 步骤 1：创建一个 Amazon Cognito 身份池
<a name="getting-started-react-create-identity-pool"></a>

在本练习中，您将创建并使用一个 Amazon Cognito 身份池，为应用程序提供对 Amazon S3 服务的无需验证身份的访问权限。创建身份池还会创建两个 AWS Identity and Access Management (IAM) 角色，一个用于支持由身份提供商进行身份验证的用户，另一个用于支持未经身份验证的访客用户。

在本练习中，我们仅使用未经身份验证的用户角色，将重点放在任务上。您可在以后集成对身份提供商和通过身份验证的用户的支持。

**创建 Amazon Cognito 身份池**

1. 登录 AWS 管理控制台 并在亚马逊 [Web Services](https://console.aws.amazon.com/cognito/) 控制台上打开 Amazon Cognito 控制台。

1. 在控制台打开页面上，选择**身份池**。

1. 在下一页上，选择**创建新的身份池**。
**注意**  
如果没有其他身份池，则 Amazon Cognito 控制台会跳过此页面并打开下一页。

1. 在**配置身份池信任**中，选择**来宾访问权限**进行用户身份验证。

1. 在**配置权限**中，选择**创建新的 IAM 角色**并在 IA **M *getStartedReact角色*名称中输入名称（例如角色**）。

1. 在**配置属性**中，在**身份*getStartedReact池*名称中输入名称（例如池**）。

1. 在**查看并创建**中，确认您为新身份池所做的选择。选择**编辑**以返回向导并更改任何设置。完成后，选择**创建身份池**。

1. 记下新创建的身份池的身份池 ID 和区域。您需要在浏览器脚本*identityPoolId*中替换*region*和这些值。

在创建 Amazon Cognito 身份池之后，您已准备好添加 React Native 应用程序所需的 Amazon S3 的权限。

## 步骤 2：将策略添加到创建的 IAM 角色
<a name="getting-started-react-iam-role"></a>

要使浏览器脚本能够访问 Amazon S3 以创建和删除 Amazon S3 存储桶，请使用为您的 Amazon Cognito 身份池创建的未经身份验证的 IAM 角色。这需要您将 IAM policy 添加到角色。有关 IAM 角色的更多信息，请参阅 I [A *M 用户指南*中的创建角色以向 AWS 服务委派权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

**将 Amazon S3 策略添加到与未经身份验证用户关联的 IAM 角色**

1. 登录 AWS 管理控制台 并打开 IAM 控制台，网址为[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在左侧导航窗格中，选择 **角色**。

1. 选择要修改的角色的名称（例如 *getStartedRole*），然后选择 “**权限**” 选项卡。

1. 选择**添加权限**，然后选择**附加策略**。

1. 在为该角色**添加权限**页面中，找到并选中 **AmazonS3 ReadOnlyAccess** 的复选框。
**注意**  
您可以使用此过程来启用对任何 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://www.npmjs.com/)上的 [Downloading and installing packages locally](https://docs.npmjs.com/downloading-and-installing-packages-locally) 和 [Creating Node.js Modules](https://docs.npmjs.com/creating-node-js-modules)。有关下载和安装适用的 AWS SDK 的信息 JavaScript，请参阅[安装适用于 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*和*region*替换为身份池 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;
```

首先导入的代码需要依赖 AWS 于 React、React Native 和 SDK。

在函数 APP 中：
+ S3Client 对象已创建，使用先前创建的 Amazon Cognito 身份池指定凭证。
+ `createBucket` 和 `deleteBucket` 方法分别用于创建和删除指定存储桶。
+ React Native View 显示文本输入字段，供用户输入 Amazon S3 存储桶名称，并提供用于创建和删除指定 Amazon S3 存储桶的按钮。

完整 JavaScript 页面可[在此处获](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/reactnative/ReactNativeApp/App.tsx)得 GitHub。

## 步骤 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_cn/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 角色。