Skip to content

Commit bbb95c2

Browse files
committed
[Flight Fixture] Extract mutations into a custom Hook
1 parent 5e8c8df commit bbb95c2

File tree

3 files changed

+46
-39
lines changed

3 files changed

+46
-39
lines changed

fixtures/flight/src/AddTodo.client.js

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,27 @@
11
import * as React from 'react';
22

33
import Container from './Container.js';
4-
import {RefreshContext} from './Context.client';
4+
import useMutation from './useMutation.client';
55

66
export default function AddTodo() {
77
const [text, setText] = React.useState('');
8-
const [startTransition, isPending] = React.unstable_useTransition();
9-
const refresh = React.useContext(RefreshContext);
8+
const [postTodo, isPosting] = useMutation(async () => {
9+
setText('');
10+
await fetch('http://localhost:3001/todos', {
11+
method: 'POST',
12+
mode: 'cors',
13+
headers: {
14+
Accept: 'application/json',
15+
'Content-Type': 'application/json',
16+
},
17+
body: JSON.stringify({text}),
18+
});
19+
});
1020
return (
1121
<Container>
1222
<input value={text} onChange={e => setText(e.target.value)} />
13-
<button
14-
onClick={async () => {
15-
await fetch('http://localhost:3001/todos', {
16-
method: 'POST',
17-
mode: 'cors',
18-
headers: {
19-
Accept: 'application/json',
20-
'Content-Type': 'application/json',
21-
},
22-
body: JSON.stringify({text}),
23-
});
24-
startTransition(() => {
25-
refresh();
26-
});
27-
}}>
28-
add
29-
</button>
30-
{isPending && ' ...'}
23+
<button onClick={() => postTodo()}>add</button>
24+
{isPosting && ' ...'}
3125
</Container>
3226
);
3327
}
Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
11
import * as React from 'react';
2-
import {RefreshContext} from './Context.client';
2+
import useMutation from './useMutation.client';
33

44
export default function DeleteTodo({id}) {
5-
const [startTransition] = React.unstable_useTransition();
6-
const refresh = React.useContext(RefreshContext);
7-
8-
return (
9-
<button
10-
onClick={async () => {
11-
await fetch('http://localhost:3001/todos/' + id, {
12-
method: 'DELETE',
13-
mode: 'cors',
14-
});
15-
startTransition(() => {
16-
refresh();
17-
});
18-
}}>
19-
x
20-
</button>
21-
);
5+
const [deleteTodo] = useMutation(async () => {
6+
await fetch('http://localhost:3001/todos/' + id, {
7+
method: 'DELETE',
8+
mode: 'cors',
9+
});
10+
});
11+
return <button onClick={() => deleteTodo()}>x</button>;
2212
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as React from 'react';
2+
3+
import {RefreshContext} from './Context.client';
4+
5+
export default function useMutation(performMutation) {
6+
const [pendingCount, setPendingCount] = React.useState(0);
7+
const [startTransition, isTransitioning] = React.unstable_useTransition();
8+
const refresh = React.useContext(RefreshContext);
9+
10+
async function handleMutation(...args) {
11+
setPendingCount(c => c + 1);
12+
try {
13+
await performMutation(...args);
14+
} finally {
15+
setPendingCount(c => c - 1);
16+
}
17+
startTransition(() => {
18+
refresh();
19+
});
20+
}
21+
22+
return [handleMutation, pendingCount > 0 || isTransitioning];
23+
}

0 commit comments

Comments
 (0)