Skip to content

Instantly share code, notes, and snippets.

@snigo
Last active February 27, 2024 17:56
Show Gist options
  • Save snigo/38c31ee2f88c9dd1045d5f8d6bd1cdfd to your computer and use it in GitHub Desktop.
Save snigo/38c31ee2f88c9dd1045d5f8d6bd1cdfd to your computer and use it in GitHub Desktop.
/** hooks/useRefresh.ts */
const useRefresh = () => {
const [, dispatch] = useReducer((bool) => !bool, true);
return dispatch;
};
/** hooks/useInit.ts */
const useInit = (fn: () => any) => {
const initialized = useRef(false);
if (!initialized.current) {
fn();
initialized.current = true;
}
};
/** state/Quotable.ts */
class Quotable {
quote = "";
error: Error | null = null;
loading = false;
async random() {
this.loading = true;
this.error = null;
try {
const response = await fetch("https://api.quotable.io/random");
if (!response.ok) {
throw new Error("Failed to fetch quote");
}
const data = await response.json();
this.quote = data.content;
} catch (error: any) {
this.error = error;
} finally {
this.loading = false;
}
}
}
/** components/QuoteOfTheDay.tsx */
const quotable = new Quotable();
function QuoteOfTheDay() {
const refresh = useRefresh();
const getRandom = () => quotable.random().finally(refresh);
useInit(getRandom);
const handleNew = () => {
getRandom();
refresh();
};
return (
<main className={styles.main}>
<h1>Quote of the Day</h1>
<blockquote>
<p>
{quotable.loading
? "Loading..."
: quotable.error
? `Error: ${quotable.error.message}`
: quotable.quote}
</p>
</blockquote>
<button onClick={handleNew}>New Quote</button>
</main>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment