Hooks & State
useAuth, 쿼리, 뮤테이션, 스토어 목록입니다.
킷의 상태는 두 갈래입니다. 서버 데이터는 TanStack Query, 토큰과 모달 상태는 Zustand입니다. 내 정보를 Zustand에 복사하지 않고 항상 useMe()로 가져옵니다.
useAuth
가장 자주 쓰는 훅입니다. 로그인 상태와 내 정보를 한 번에 줍니다.
tsx
const { user, isAuthenticated, isLoading, isAdmin } = useAuth();| 값 | 타입 | 설명 |
|---|---|---|
user | User | undefined | 내 정보. 로그인 전이면 undefined |
isAuthenticated | boolean | 액세스 토큰이 있는지 |
isLoading | boolean | 내 정보를 불러오는 중인지 |
isAdmin | boolean | 역할이 MASTER인지 |
Examples
로그인한 사용자 이름 보여 주기
tsx
const { user, isLoading } = useAuth();
if (isLoading) return <p>불러오는 중…</p>;
return <p>{user ? `${user.name}님` : "로그인이 필요합니다"}</p>;역할에 따라 버튼 보이기
tsx
const { user } = useAuth();
const canWrite = ["MASTER", "OWNER", "WRITER"].includes(user?.role.name ?? "");
{canWrite && <Button>새 글 쓰기</Button>}로그아웃 버튼 직접 만들기
tsx
const logout = useLogout();
<Button onClick={() => logout.mutate()} disabled={logout.isPending}>로그아웃</Button>Queries
| 훅 | 반환 | 쿼리 키 |
|---|---|---|
useMe() | 내 정보 (토큰이 있을 때만 실행) | ["meerkit", "me"] |
useMembers(query) | 조건에 맞는 한 페이지 { items, total, page, size } (관리자) | ["meerkit", "admin", "members", query] |
Mutations
| 훅 | 호출 | 성공 시 |
|---|---|---|
useLogin() | mutate({ user_id, password }) | 토큰 저장, 모달 닫기 |
useSignup() | mutate({ user_id, name, email, password }) | 가입 후 자동 로그인 |
useLogout() | mutate() | 토큰 제거, 내 정보 캐시 삭제 |
useUpdateRoles() | mutate({ id, roles }) | 멤버 목록 다시 불러오기 (PUT /users/{id}/roles) |
useUpdateActive() | mutate({ id, isActive }) | 활성/비활성·잠금 해제·탈퇴 취소 후 목록 다시 불러오기 (PATCH /users/{id}/active) |
useRemoveMember() | mutate(id) | 멤버 목록 다시 불러오기 |
useForgotPassword() | mutate({ email }) | isSuccess가 true가 되면 안내 화면 |
useSendEmailCode() | mutate({ email }) | 인증번호 발송 (이메일 인증 사용 시) |
useVerifyEmailCode() | mutate({ email, code }) | 성공하면 { token } 반환 |
useResetPassword() | mutate({ token, password }) | isSuccess가 true가 되면 완료 화면 |
useUpdateProfile() | mutate({ name, email, ... }) | 내 정보 캐시 갱신, 토스트 |
useChangePassword() | mutate({ current_password, new_password }) | 토스트 |
Stores
useAuthStore
tsx
const accessToken = useAuthStore((s) => s.accessToken);
const setAccessToken = useAuthStore((s) => s.setAccessToken);토큰 스토어에
persist를 쓰지 마세요. 액세스 토큰은 메모리에만 있어야 합니다.useAuthDialog
tsx
const { open, mode, openDialog, closeDialog, setMode } = useAuthDialog();
// mode: "login" | "signup" | "forgot"useLockoutStore · useLoginLockout
로그인 실패 횟수와 잠금 시각입니다. sessionStorage에 저장되어 새로고침해도 유지됩니다 (Login Lockout 참고).
tsx
const { lockedUntil, attemptsLeft } = useLoginLockout();액세스 토큰 스토어에는
persist를 쓰지 않지만, 잠금 스토어는 의도적으로 sessionStorage에 저장합니다. 토큰과 달리 민감하지 않은 값이기 때문입니다.Config
사용자가 고치는 설정은 프로젝트 루트의 meerkit.config.ts이고, 코드에서 읽는 값은 meerkitConfig입니다.
| 키 | 타입 | 기본값 | 설명 |
|---|---|---|---|
theme | "meerkit" | "shadcn" | meerkit | 스타일 모드 (Theming 참고) |
motion | boolean | true | false면 Meerkit 애니메이션 끄기 |
signup.passwordConfirm | boolean | false | 가입 폼에 비밀번호 확인 추가 |
signup.optionalFields | SignupOptionalField[] | [] | 가입 폼의 선택 항목 (nickname, phone, address, birth_date, gender) |
signup.addressType | "basic" | "postcode" | basic | 주소 입력 방식 (주소+상세 / 우편번호+주소+상세) |
signup.addressSearch | "popup" | "dialog" | popup | 주소 검색 방식 (카카오 팝업 / 검색 창) |
signup.nickname | { generator, autoFill } | { true, false } | 닉네임 [자동 생성] 버튼, 가입 폼 미리 채우기 |
signup.emailVerification | boolean | false | 이메일 인증번호 받기·확인 사용 여부 |
signup.terms | TermsItem[] | 약관 3종 | 가입 시 동의받을 약관. 빈 배열이면 숨김 |
loading.variant | LoaderVariant | "ring" | 불러오는 중 표시 스타일 9종 중 하나 |
ai.voice.colors | string[] | 파랑·보라·분홍·청록 | 음성 입력 파동 색 (2개 이상) |
login.maxAttempts | number | 5 | 연속 실패 허용 횟수. 0이면 잠금 끄기 |
login.lockMinutes | number | 5 | 잠금 시간(분) |
tsx
import { meerkitConfig } from "@/meerkit";
meerkitConfig.routes.adminMembers; // "/admin/members"
meerkitConfig.docsUrl; // 웰컴 페이지 Docs 링크