# claude session d02659b5-ec03-4d34-b363-1f0767df0d19
## User
On slow 3G the checkout button flickers and some people manage to place the order twice. Fix it.
### Tool call: `Read`
```
{
"file_path": "/home/dev/code/web-app/src/components/CheckoutButton.tsx"
}
```
### Tool result
```
1 export function CheckoutButton({ cart }: { cart: Cart }) {
2 const [loading, setLoading] = useState(false);
3
4 async function submit() {
5 setLoading(true);
6 await placeOrder(cart);
7 setLoading(false);
8 }
9
10 return ;
11 }
```
### Assistant (thinking)
The button is never disabled, so a second tap during the request fires submit again. The flicker is the label swapping to a spinner, which changes the button width. Disable while pending, guard with a ref (state updates are async, two fast taps both see loading=false), and keep the width fixed.
### Tool call: `Edit`
```
{
"file_path": "/home/dev/code/web-app/src/components/CheckoutButton.tsx",
"old_string": " const [loading, setLoading] = useState(false);\n\n async function submit() {\n setLoading(true);\n await placeOrder(cart);\n setLoading(false);\n }\n\n return ;\n",
"new_string": " const [loading, setLoading] = useState(false);\n const inFlight = useRef(false); // two quick taps both see loading=false\n\n async function submit() {\n if (inFlight.current) return;\n inFlight.current = true;\n setLoading(true);\n try {\n await placeOrder(cart);\n } finally {\n inFlight.current = false;\n setLoading(false);\n }\n }\n\n return (\n \n );\n"
}
```
### Tool result
```
The file src/components/CheckoutButton.tsx has been updated.
```
### Tool call: `Bash`
```
{
"command": "npx tsc --noEmit",
"description": "Type check"
}
```
### Tool result
```
```
## Assistant
The button is disabled while the order is pending, a ref blocks a second tap that lands before the re-render, and a fixed min-width stops the flicker when the label swaps to the spinner.
### Tool call: `Bash`
```
{
"command": "git commit -am \"Disable checkout button while the order is pending\"",
"description": "Commit"
}
```