Skip to content

Commit

Permalink
Render server action result instead of logging it
Browse files Browse the repository at this point in the history
  • Loading branch information
unstubbable committed Mar 3, 2023
1 parent 4e39e06 commit c26cd1d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/client-components/buy-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import * as React from 'react';
import type {buy} from '../server-actions/buy.js';
import {useEphemeralState} from './use-ephemeral-state.js';

export interface BuyButtonProps {
readonly buy: typeof buy;
Expand All @@ -10,12 +11,12 @@ export interface BuyButtonProps {
export function BuyButton({buy}: BuyButtonProps): JSX.Element {
const [quantity, setQuantity] = React.useState(1);
const [isPending, setIsPending] = React.useState(false);
const [result, setResult] = useEphemeralState<string>(undefined, 3000);

const handleClick = async () => {
setIsPending(true);
const result = await buy(quantity);
setResult(await buy(quantity));
setIsPending(false);
console.log(result);
};

return (
Expand All @@ -33,6 +34,7 @@ export function BuyButton({buy}: BuyButtonProps): JSX.Element {
<button onClick={handleClick} disabled={isPending}>
Buy now
</button>
{result && <p style={{color: `forestgreen`}}>{result}</p>}
</div>
);
}
26 changes: 26 additions & 0 deletions src/client-components/use-ephemeral-state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from 'react';

export function useEphemeralState<S>(
initialState: S | undefined | (() => S | undefined),
lifetimeInMilliseconds: number,
): [S | undefined, React.Dispatch<React.SetStateAction<S | undefined>>] {
const [state, setState] = React.useState(initialState);
const timeoutRef = React.useRef<number>();

const setEphemeralState = React.useCallback<
React.Dispatch<React.SetStateAction<S | undefined>>
>((value) => {
window.clearTimeout(timeoutRef.current);

timeoutRef.current = window.setTimeout(
() => setState(undefined),
lifetimeInMilliseconds,
);

setState(value);
}, []);

React.useEffect(() => () => window.clearTimeout(timeoutRef.current), []);

return [state, setEphemeralState];
}
2 changes: 1 addition & 1 deletion src/server-actions/buy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
export async function buy(quantity: number): Promise<string> {
await new Promise((resolve) => setTimeout(resolve, 500));

return `Bought ${quantity} items.`;
return `Bought ${quantity} ${quantity === 1 ? `item` : `items`}.`;
}

0 comments on commit c26cd1d

Please sign in to comment.