😱
<備忘録>Amplifyハンズオンにハマった話(export 'API' (imported as 'API') was not found
試したハンズオン
フルスタック React アプリケーションを構築する
AWS Amplify を使用してシンプルなウェブアプリケーションを作成する
所用時間:50 分と書いてあったから気軽に始めたら少しハマってしまった。
5つのモジュールに分かれている。
1、REACT アプリケーションをデプロイおよびホストする
概ねスムーズに終わる
2、ローカル Amplify アプリを初期化する
概ねスムーズに終わる
3、認証を追加する
(未検証)
4、 GraphQL API とデータベースを追加する
src/App.js のサンプルソースがエラーで実行できない!!
export 'API' (imported as 'API') was not found in 'aws-amplify' (possible exports: Amplify)
以下のissueに上がっているものをみると
2023年11月ころにでたAmplify V6だとimport { API } from "aws-amplify";
ではなく
import { Amplify } from 'aws-amplify';
import { generateClient } from 'aws-amplify/api';
import config from './amplifyconfiguration.json';
Amplify.configure(config);
const client = generateClient();
という書き方に変わっているので、これ移行のハンズオンはV6のやり方で書かないとエラーがでるようだ。
モジュール4でうまくいったソース。
import React, { useState, useEffect } from "react";
import "./App.css";
import "@aws-amplify/ui-react/styles.css";
import { Amplify } from 'aws-amplify';
import { generateClient } from 'aws-amplify/api';
import { createTodo, deleteTodo } from './graphql/mutations';
import config from './amplifyconfiguration.json';
import { listTodos } from './graphql/queries';
import {
Button,
Flex,
Heading,
Text,
TextField,
View,
withAuthenticator,
} from "@aws-amplify/ui-react";
Amplify.configure(config);
const API = generateClient();
const App = ({ signOut }) => {
const [notes, setNotes] = useState([]);
useEffect(() => {
fetchNotes();
}, []);
async function fetchNotes() {
const apiData = await API.graphql({ query: listTodos });
const notesFromAPI = apiData.data.listTodos.items;
setNotes(notesFromAPI);
}
async function createNote(event) {
event.preventDefault();
const form = new FormData(event.target);
const data = {
name: form.get("name"),
description: form.get("description"),
};
await API.graphql({
query: createTodo,
variables: { input: data },
});
fetchNotes();
event.target.reset();
}
async function deleteNote({ id }) {
const newNotes = notes.filter((note) => note.id !== id);
setNotes(newNotes);
await API.graphql({
query: deleteTodo,
variables: { input: { id } },
});
}
return (
<View className="App">
<Heading level={1}>My Notes App</Heading>
<View as="form" margin="3rem 0" onSubmit={createNote}>
<Flex direction="row" justifyContent="center">
<TextField
name="name"
placeholder="Note Name"
label="Note Name"
labelHidden
variation="quiet"
required
/>
<TextField
name="description"
placeholder="Note Description"
label="Note Description"
labelHidden
variation="quiet"
required
/>
<Button type="submit" variation="primary">
Create Note
</Button>
</Flex>
</View>
<Heading level={2}>Current Notes</Heading>
<View margin="3rem 0">
{notes.map((note) => (
<Flex
key={note.id || note.name}
direction="row"
justifyContent="center"
alignItems="center"
>
<Text as="strong" fontWeight={700}>
{note.name}
</Text>
<Text as="span">{note.description}</Text>
<Button variation="link" onClick={() => deleteNote(note)}>
Delete note
</Button>
</Flex>
))}
</View>
<Button onClick={signOut}>Sign Out</Button>
</View>
);
};
export default withAuthenticator(App);
感想
V5のハンズオン多いだろうから意識しないとひっかかりそう。
サクッと検証終わらせるつもりがV6が動いててハマった話でした。
モジュール6も今度検証の続きをやってみます。。。
Discussion