-tsCode: "import React, { useCallback, useState, useEffect } from 'react';\r\n\r\n// Usage\r\nfunction App() {\r\n const { execute, status, value, error } = useAsync<string>(myFunction, false);\r\n\r\n return (\r\n <div>\r\n {status === 'idle' && <div>Start your journey by clicking a button</div>}\r\n {status === 'success' && <div>{value}</div>}\r\n {status === 'error' && <div>{error}</div>}\r\n <button onClick={execute} disabled={status === 'pending'}>\r\n {status !== 'pending' ? 'Click me' : 'Loading...'}\r\n </button>\r\n </div>\r\n );\r\n}\r\n\r\n// An async function for testing our hook.\r\n// Will be successful 50% of the time.\r\nconst myFunction = (): Promise<string> => {\r\n return new Promise((resolve, reject) => {\r\n setTimeout(() => {\r\n const rnd = Math.random() * 10;\r\n rnd <= 5\r\n ? resolve('Submitted successfully 🙌')\r\n : reject('Oh no there was an error 😞');\r\n }, 2000);\r\n });\r\n};\r\n\r\n// Hook\r\nconst useAsync = <T, E = string>(\r\n asyncFunction: () => Promise<T>,\r\n immediate = true\r\n) => {\r\n const [status, setStatus] = useState<\r\n 'idle' | 'pending' | 'success' | 'error'\r\n >('idle');\r\n const [value, setValue] = useState<T | null>(null);\r\n const [error, setError] = useState<E | null>(null);\r\n\r\n // The execute function wraps asyncFunction and\r\n // handles setting state for pending, value, and error.\r\n // useCallback ensures the below useEffect is not called\r\n // on every render, but only if asyncFunction changes.\r\n const execute = useCallback(() => {\r\n setStatus('pending');\r\n setValue(null);\r\n setError(null);\r\n\r\n return asyncFunction()\r\n .then((response: any) => {\r\n setValue(response);\r\n setStatus('success');\r\n })\r\n .catch((error: any) => {\r\n setError(error);\r\n setStatus('error');\r\n });\r\n }, [asyncFunction]);\r\n\r\n // Call execute if we want to fire it right away.\r\n // Otherwise execute can be called later, such as\r\n // in an onClick handler.\r\n useEffect(() => {\r\n if (immediate) {\r\n execute();\r\n }\r\n }, [execute, immediate]);\r\n\r\n return { execute, status, value, error };\r\n};"
0 commit comments