我正在关注亚马逊的 AWS 入门:https ://aws.amazon.com/getting-started/hands-on/build-react-app-amplify-graphql/module-four/
我已经构建了应用程序并将其托管在 git 上。每当我刷新页面或重新运行“npm start”时,我的笔记应用程序中有两个条目,即使在我删除它们之后也是如此。
https://i.stack.imgur.com/pRlLC.png
当我删除笔记并输入新的“笔记”时,我收到错误:“列表中的每个孩子都应该有一个唯一的“关键”道具。” 当我删除注释时,我收到错误消息:“Uncaught (in promise)”DynamoDB:DynamoDbException
https://i.stack.imgur.com/2pMEG.png
感谢您的关注!app.js 中的代码如下:
import React, { useState, useEffect } from 'react';
import './App.css';
import { API, Storage } from 'aws-amplify';
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';
import { listNotes } from './graphql/queries';
import { createNote as createNoteMutation, deleteNote as deleteNoteMutation } from './graphql/mutations';
const initialFormState = { name: '', description: '' }
function App() {
const [notes, setNotes] = useState([]);
const [formData, setFormData] = useState(initialFormState);
useEffect(() => {
fetchNotes();
}, []);
async function onChange(e) {
if (!e.target.files[0]) return
const file = e.target.files[0];
setFormData({ ...formData, image: file.name });
await Storage.put(file.name, file);
fetchNotes();
}
async function fetchNotes() {
const apiData = await API.graphql({ query: listNotes });
const notesFromAPI = apiData.data.listNotes.items;
await Promise.all(notesFromAPI.map(async note => {
if (note.image) {
const image = await Storage.get(note.image);
note.image = image;
}
return note;
}))
setNotes(apiData.data.listNotes.items);
}
async function createNote() {
if (!formData.name || !formData.description) return;
await API.graphql({ query: createNoteMutation, variables: { input: formData } });
if (formData.image) {
const image = await Storage.get(formData.image);
formData.image = image;
}
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 (
<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}
/>
<input
type="file"
onChange={onChange}
/>
<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>
{
note.image && <img src={note.image} style={{width: 400}} />
}
</div>
))
}
</div>
<AmplifySignOut />
</div>
);
}
export default withAuthenticator(App);