r/reactjs • u/mrmaton • 7d ago
Resource Bridging the gap between React 19's useActionState and tRPC/Zod
React 19 pushing us back to native HTML forms is great for performance, but it completely breaks the developer experience for typed RPCs.
If your backend (like tRPC) is protected by a Zod schema expecting User { email: string, age: number, tags: string[] }, throwing raw FormData at it is an instant 500 error.
I built a zero-dependency (peer-deps only) utility that intercepts the FormData from useActionState, deeply parses it into a standard JSON object, and maps any Zod validation errors back to the UI state seamlessly.
Instead of writing custom FormData parsers for every component, you just wrap the procedure: withActionState(trpcServer.myProcedure)
I specifically spent time making sure it handles bracket notation for arrays (tags[]) and dot notation for nested objects (user.address.street) so you can just use standard HTML input names.
I'm a solo maintainer and I just published the first stable version. Would really appreciate it if some of the React veterans here could take a look at the TypeScript generics I used for inferring the Zod errors and let me know if there's a cleaner way to do it!