useServerAction
The useServerAction hook simplifies server action management in Next.js client components.
It uses SWR for efficient data fetching, offers conditional execution, and provides easy access
to loading states, errors, and data. This TypeScript-friendly hook streamlines the process of
integrating server actions into React components with minimal boilerplate.
Usage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44"use client"; import { useEffect, useState } from "react"; import useServerAction from "@/hooks/use-server-action"; export default function Example({ name }: { name: string }) { const [shouldFetch, setShouldFetch] = useState(false); const { data, error, isLoading, mutate } = useServerAction( async () => { return `Hello ${name}!`; }, [name], { shouldFetch } ); // Refresh the data every second useEffect(() => { const interval = setInterval(() => { mutate(); }, 1000); return () => clearInterval(interval); }, [mutate]); // Conditionally control whether to start fetching the data useEffect(() => { const timer = setTimeout(() => { setShouldFetch(true); }, 5000); return () => clearTimeout(timer); }, []); if (isLoading) { return <div>Loading...</div>; } if (error) { return <div>Error: {error.message}</div>; } return <div>{data}</div>; }
Installation
1
npx shadcn add "https://registry.niels.foo/use-server-action.json"With Persistence
By default, useServerAction operates purely in memory, and the cache is cleared
when the tab is closed. To enable persistence across sessions, set the persist option to true.
When persistence is enabled, it modifies the behavior of SWR's isLoading state:
- Initially,
isLoadingis set totrue. - If cached data is available,
isLoadingis immediately set tofalse. - During the actual fetch,
isLoadingremainsfalse. You should look atisValidatinginstead anyway.
This differs from SWR's default behavior, where isLoading only becomes false
after the fetch is completed, regardless of cached data availability.
1 2 3 4 5 6 7const { data, isLoading } = useServerAction( async () => { return `Hello ${name}!`; }, [name], { persist: true } );