AWS Reactチュートリアルはサンプルが動作しないため修正が必要。GraphQL APIの設定手順など、他にも実際の処理は大きく異なるが、デフォルト設定で進めばできてしまうので、特に影響の大きいGraphQLとDynamoDBを操作するApp.jsの修正方法について説明する。
Build a Full-Stack React Application – Module 4: Add a GraphQL API and Database
https://aws.amazon.com/getting-started/hands-on/build-react-app-amplify-graphql/module-four/
ビルドエラー
モジュール3のAWS Amplify認証サービスで修正が必要だったように、このモジュール4のサンプルアプリもそのままのサンプルコードを使うと以下のエラーが発生する。
src/App.js修正コード
以下のコードを使うことでこのサンプルアプリを動作させることが可能。主な変更点はモジュール3の認証サービスの処理の部分。
import React, { useState, useEffect } from 'react';
import './App.css';
import { API } from 'aws-amplify';
import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import { listNotes } from './graphql/queries';
import { createNote as createNoteMutation, deleteNote as deleteNoteMutation } from './graphql/mutations';
const initialFormState = { name: '', description: '' }
export default function App() {
const [notes, setNotes] = useState([]);
const [formData, setFormData] = useState(initialFormState);
useEffect(() => {
fetchNotes();
}, []);
async function fetchNotes() {
const apiData = await API.graphql({ query: listNotes });
setNotes(apiData.data.listNotes.items);
}
async function createNote() {
if (!formData.name || !formData.description) return;
await API.graphql({ query: createNoteMutation, variables: { input: formData } });
setNotes([ ...notes, formData ]);
setFormData(initialFormState);
}
async function deleteNote({ id }) {
const newNotesArray = notes.filter(note => note.id !== id);
setNotes(newNotesArray);
await API.graphql({ query: deleteNoteMutation, variables: { input: { id } }});
}
return (
<Authenticator>
{({ signOut, user }) => (
<div className="App">
<h1>My Notes App</h1>
<input
onChange={e => setFormData({ ...formData, 'name': e.target.value})}
placeholder="Note name"
value={formData.name}
/>
<input
onChange={e => setFormData({ ...formData, 'description': e.target.value})}
placeholder="Note description"
value={formData.description}
/>
<button onClick={createNote}>Create Note</button>
<div style={{marginBottom: 30}}>
{
notes.map(note => (
<div key={note.id || note.name}>
<h2>{note.name}</h2>
<p>{note.description}</p>
<button onClick={() => deleteNote(note)}>Delete note</button>
</div>
))
}
</div>
<button onClick={signOut} class="amplify-button" data-variation="primary" type="submit">Sign out</button>
</div>
)}
</Authenticator>
);
}