rsnext/examples/with-apollo/components/Submit.js
Henrik Wenz a79bcfb73a
Fix with-apollo example (#17686)
# Issue

The cache updates are performed in a wrong way, resulting in a duplicate collection:

**Error:**

```log
webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:88 Warning: Encountered two children with the same key, `6f3f7265-0d97-4708-a3ea-7dee76dc0a0a`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
```

**Video:**

![broken](https://user-images.githubusercontent.com/1265681/95336501-0c170180-08b1-11eb-9273-6ac9e37ceb41.gif)

# Fix

**Video:**

![fixed](https://user-images.githubusercontent.com/1265681/95336538-15a06980-08b1-11eb-8d5e-6acc07e16138.gif)
2020-10-08 03:45:28 +00:00

73 lines
1.7 KiB
JavaScript

import { gql, useMutation } from '@apollo/client'
const CREATE_POST_MUTATION = gql`
mutation createPost($title: String!, $url: String!) {
createPost(title: $title, url: $url) {
id
title
votes
url
createdAt
}
}
`
export default function Submit() {
const [createPost, { loading }] = useMutation(CREATE_POST_MUTATION)
const handleSubmit = (event) => {
event.preventDefault()
const form = event.target
const formData = new window.FormData(form)
const title = formData.get('title')
const url = formData.get('url')
form.reset()
createPost({
variables: { title, url },
update: (cache, { data: { createPost } }) => {
cache.modify({
fields: {
allPosts(existingPosts = []) {
const newPostRef = cache.writeFragment({
data: createPost,
fragment: gql`
fragment NewPost on allPosts {
id
type
}
`,
})
return [newPostRef, ...existingPosts]
},
},
})
},
})
}
return (
<form onSubmit={handleSubmit}>
<h1>Submit</h1>
<input placeholder="title" name="title" type="text" required />
<input placeholder="url" name="url" type="url" required />
<button type="submit" disabled={loading}>
Submit
</button>
<style jsx>{`
form {
border-bottom: 1px solid #ececec;
padding-bottom: 20px;
margin-bottom: 20px;
}
h1 {
font-size: 20px;
}
input {
display: block;
margin-bottom: 10px;
}
`}</style>
</form>
)
}