Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
1import React from 'react';
2import { gql, useQuery, useMutation } from 'urql';
3
4const LINKS_QUERY = gql`
5 query Links($first: Int!) {
6 links(first: $first) {
7 nodes {
8 id
9 title
10 canonicalUrl
11 }
12 }
13 }
14`;
15
16const CREATE_LINK_MUTATION = gql`
17 mutation CreateLink($url: URL!) {
18 createLink(url: $url) {
19 node {
20 id
21 title
22 canonicalUrl
23 }
24 }
25 }
26`;
27
28const Links = () => {
29 const [linksResult] = useQuery({
30 query: LINKS_QUERY,
31 variables: { first: 10 },
32 });
33 const [createResult, createLink] = useMutation(CREATE_LINK_MUTATION);
34
35 const onSubmitLink = event => {
36 event.preventDefault();
37 const { target } = event;
38 createLink({ url: new FormData(target).get('link') }).then(() =>
39 target.reset()
40 );
41 };
42
43 return (
44 <div>
45 {linksResult.error && <p>Oh no... {linksResult.error.message}</p>}
46
47 {linksResult.data && (
48 <ul>
49 {linksResult.data.links.nodes.map(link => (
50 <li key={link.id}>
51 <a rel="noreferrer" href={link.canonicalUrl}>
52 {link.title}
53 </a>
54 </li>
55 ))}
56 </ul>
57 )}
58
59 <form onSubmit={onSubmitLink}>
60 {createResult.fetching ? <p>Submitting...</p> : null}
61 {createResult.error ? (
62 <p>Oh no... {createResult.error.message}</p>
63 ) : null}
64
65 <fieldset disabled={createResult.fetching ? 'disabled' : null}>
66 <label>
67 {'Link to Blog Post: '}
68 <input type="url" name="link" placeholder="https://..." />
69 </label>
70 <button type="submit">Add Link</button>
71 </fieldset>
72 </form>
73 </div>
74 );
75};
76
77export default Links;