Created
June 28, 2024 14:35
-
-
Save floatrx/f541d9a154e2da40b8f00e5fda772fdd to your computer and use it in GitHub Desktop.
useServerAction with examples #hook #nextjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use server'; | |
import type { TNote } from '@/types/note'; | |
import { revalidatePath } from 'next/cache'; | |
import { noteService } from '@/features/note/services/note'; | |
export async function deleteNote(id: TNote['id']) { | |
const { error } = await noteService.remove(id); | |
if (error) return; | |
revalidatePath('/notes'); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from 'react'; | |
type AsyncFn = (...args: any) => Promise<any>; | |
/** | |
* Use this hook to execute server actions in the client side | |
* It will handle loading, error and data states... | |
* @param action | |
* @example | |
* export const DeleteButton = ({id}) => { | |
* const { loading, execute } = useServerAction(deleteNote); | |
* return ( | |
* <Button isLoading={loading} onClick={() => execute(id)}>Delete</Button> | |
* ); | |
* }; | |
*/ | |
export const useServerAction = <T extends AsyncFn>(action: T) => { | |
const [loading, setLoading] = useState(false); | |
const [error, setError] = useState<Error | null>(null); | |
const [data, setData] = useState<Awaited<ReturnType<T>> | null>(null); | |
const execute = async (...args: Parameters<T>) => { | |
setLoading(true); | |
setError(null); | |
setData(null); | |
try { | |
const res = await action(...args); | |
setData(res); | |
return res as Awaited<ReturnType<T>>; | |
} catch (e) { | |
console.log('Error:', e.message); | |
setError(e); | |
} finally { | |
setLoading(false); | |
} | |
}; | |
return { | |
data, | |
loading, | |
error, | |
execute, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment