From 31357786a04141aad39dbf9afeb083d2f7c68892 Mon Sep 17 00:00:00 2001 From: Application-drop-up Date: Sun, 5 Jul 2026 18:36:05 +0900 Subject: [PATCH] feat(user): add useCreateUser hook --- .../features/user/hooks/use-create-user.ts | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 client/src/app/features/user/hooks/use-create-user.ts diff --git a/client/src/app/features/user/hooks/use-create-user.ts b/client/src/app/features/user/hooks/use-create-user.ts new file mode 100644 index 0000000..80d597b --- /dev/null +++ b/client/src/app/features/user/hooks/use-create-user.ts @@ -0,0 +1,42 @@ +import { useCallback, useEffect, useRef, useState } from "react"; +import { createUser } from "../apis"; +import { toCreateUserRequest } from "../mapper/to-create-user-request"; +import type { ApiUserDto } from "../apis/user-api"; +import type { CreateUserFormValues } from "../types"; + +const isAbortError = (e: unknown): boolean => { + return e instanceof DOMException && e.name === "AbortError"; +}; + +export function useCreateUser() { + const [data, setData] = useState(null); + const [isLoading, setLoading] = useState(false); + const [error, setError] = useState(null); + const abortRef = useRef(null); + + useEffect(() => { + return () => abortRef.current?.abort(); + }, []); + + const submit = useCallback(async (values: CreateUserFormValues) => { + abortRef.current?.abort(); + const abortController = new AbortController(); + abortRef.current = abortController; + + setLoading(true); + setError(null); + + try { + const created = await createUser(toCreateUserRequest(values), { + signal: abortController.signal, + }); + setData(created); + } catch (e) { + if (!isAbortError(e)) setError(e); + } finally { + setLoading(false); + } + }, []); + + return { submit, data, isLoading, error }; +}