{"id":16669,"library":"react-query-auth","title":"React Query Authentication Hooks","description":"react-query-auth is a specialized library designed to streamline user authentication management within React applications by leveraging `@tanstack/react-query`. It provides a `configureAuth` function that acts as a factory, generating custom hooks (`useUser`, `useLogin`, `useRegister`, `useLogout`) and an `AuthLoader` component. These utilities abstract away the complexities of integrating authentication state with React Query's caching mechanisms, treating user data as server state. The current stable version is `2.4.3`. While no explicit release cadence is stated, the versioning suggests active maintenance and development. Its key differentiator lies in its deep integration with React Query, offering a consistent approach to manage authentication alongside other server-derived data, reducing boilerplate for common authentication flows. It requires users to provide their own API interaction functions for fetching, logging in, registering, and logging out, making it adaptable to any backend or authentication method.","status":"active","version":"2.4.3","language":"javascript","source_language":"en","source_url":"https://github.com/alan2207/react-query-auth","tags":["javascript","typescript"],"install":[{"cmd":"npm install react-query-auth","lang":"bash","label":"npm"},{"cmd":"yarn add react-query-auth","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-query-auth","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for integrating authentication state with React Query's caching and query management system.","package":"@tanstack/react-query","optional":false},{"reason":"Fundamental UI library for building React components and using React hooks.","package":"react","optional":false}],"imports":[{"note":"This is the primary factory function for setting up authentication hooks. It is a named export.","wrong":"const configureAuth = require('react-query-auth').configureAuth;","symbol":"configureAuth","correct":"import { configureAuth } from 'react-query-auth';"},{"note":"The `AuthLoader` component helps manage loading states during initial user fetching. It is a named export.","wrong":"const { AuthLoader } = require('react-query-auth');","symbol":"AuthLoader","correct":"import { AuthLoader } from 'react-query-auth';"},{"note":"These authentication-specific hooks are *returned* by the `configureAuth` function and should not be imported directly from the package.","symbol":"{ useUser, useLogin, useRegister, useLogout }","correct":"const { useUser, useLogin, useRegister, useLogout } = configureAuth({...});"}],"quickstart":{"code":"import React from 'react';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\nimport { configureAuth, AuthLoader } from 'react-query-auth';\n\nconst queryClient = new QueryClient();\n\n// Mock API functions for demonstration\nconst api = {\n  get: async (url: string) => {\n    if (url === '/me') {\n      // Simulate authenticated user\n      const user = localStorage.getItem('mock-user');\n      return user ? JSON.parse(user) : null;\n    }\n    throw new Error('Not found');\n  },\n  post: async (url: string, data?: any) => {\n    if (url === '/login' && data.email === 'test@example.com' && data.password === 'password') {\n      const user = { id: '123', email: data.email };\n      localStorage.setItem('mock-user', JSON.stringify(user));\n      return user;\n    }\n    if (url === '/register') {\n      const user = { id: '456', email: data.email };\n      localStorage.setItem('mock-user', JSON.stringify(user));\n      return user;\n    }\n    if (url === '/logout') {\n      localStorage.removeItem('mock-user');\n      return null;\n    }\n    throw new Error('API Error');\n  }\n};\n\nconst { useUser, useLogin, useLogout } = configureAuth({\n  userFn: () => api.get('/me'),\n  loginFn: (credentials) => api.post('/login', credentials),\n  registerFn: (credentials) => api.post('/register', credentials),\n  logoutFn: () => api.post('/logout')\n});\n\nfunction UserInfo() {\n  const user = useUser();\n  const logout = useLogout();\n\n  if (user.isLoading) {\n    return <div>Loading user info...</div>;\n  }\n\n  if (user.error) {\n    return <div style={{ color: 'red' }}>Error: {user.error.message}</div>;\n  }\n\n  if (!user.data) {\n    return (\n      <div>\n        <div>Not logged in</div>\n        <button onClick={() => useLogin().mutate({ email: 'test@example.com', password: 'password' })}>Login</button>\n      </div>\n    );\n  }\n\n  return (\n    <div>\n      <div>Logged in as {user.data.email}</div>\n      <button disabled={logout.isLoading} onClick={() => logout.mutate({})}>\n        Log out\n      </button>\n    </div>\n  );\n}\n\nfunction AuthScreen() {\n  const login = useLogin();\n  const register = useRegister();\n\n  const handleLogin = () => login.mutate({ email: 'test@example.com', password: 'password' });\n  const handleRegister = () => register.mutate({ email: 'new@example.com', password: 'password' });\n\n  return (\n    <div>\n      <h2>Authentication</h2>\n      <button onClick={handleLogin}>Login as Test User</button>\n      <button onClick={handleRegister}>Register New User</button>\n      {login.error && <div style={{ color: 'red' }}>Login Error: {login.error.message}</div>}\n      {register.error && <div style={{ color: 'red' }}>Register Error: {register.error.message}</div>}\n    </div>\n  );\n}\n\nfunction App() {\n  return (\n    <QueryClientProvider client={queryClient}>\n      <h1>My Auth App</h1>\n      <AuthLoader\n        renderLoading={() => <div>Initial authentication check...</div>}\n        renderUnauthenticated={() => <AuthScreen />}\n      >\n        <UserInfo />\n      </AuthLoader>\n    </QueryClientProvider>\n  );\n}\n\nexport default App;\n","lang":"typescript","description":"This quickstart demonstrates how to configure `react-query-auth` with mock API functions, use the generated `useUser`, `useLogin`, and `useLogout` hooks, and implement the `AuthLoader` component to manage initial loading and authentication states within a React Query application."},"warnings":[{"fix":"Ensure your application's root (or relevant section) is wrapped with `<QueryClientProvider client={queryClient}>...</QueryClientProvider>` where `queryClient` is an instance of `QueryClient`.","message":"All `react-query-auth` hooks and components, including the output of `configureAuth`, *must* be used within a `@tanstack/react-query` `QueryClientProvider`.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Implement your `userFn`, `loginFn`, `registerFn`, `logoutFn` to correctly interact with your backend API, returning Promises that resolve with user data or `null` for an unauthenticated state, as appropriate.","message":"This library requires you to provide the actual API interaction functions (`userFn`, `loginFn`, `registerFn`, `logoutFn`). It does not handle network requests or authentication methods (e.g., JWT, OAuth) itself.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Install or upgrade `@tanstack/react-query` to a version compatible with `react-query-auth` (e.g., `>=4.24.6` for `react-query-auth@2.x`). Refer to the `peerDependencies` in `package.json` for precise requirements.","message":"The library explicitly lists `@tanstack/react-query` as a peer dependency. Using an incompatible or significantly older version may lead to runtime errors or unexpected behavior.","severity":"breaking","affected_versions":"<2.4.3"},{"fix":"Provide a unique `userKey` array in the `configureAuth` options for each distinct authentication system, e.g., `userKey: ['admin-user']`.","message":"The `userKey` option in `configureAuth` defaults to `['authenticated-user']`. If you manage multiple independent authentication systems within a single React Query instance, these keys could conflict, leading to incorrect user state.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Wrap the root of your application (or the relevant component subtree) with `<QueryClientProvider client={new QueryClient()}>...</QueryClientProvider>`.","cause":"The application is attempting to use `react-query-auth` hooks or components without a `QueryClientProvider` higher in the component tree.","error":"Error: No QueryClient set, use QueryClientProvider to set one in the tree."},{"fix":"Ensure `configureAuth` is imported using named import syntax: `import { configureAuth } from 'react-query-auth';`.","cause":"Incorrect import syntax, typically using CommonJS `require()` or a default import for a named export in an ES module environment.","error":"TypeError: (0 , react_query_auth__WEBPACK_IMPORTED_MODULE_0__.configureAuth) is not a function"},{"fix":"Verify that your `userFn` and `loginFn` correctly return a Promise that resolves to an object containing the user's data or `null` for an unauthenticated state. Debug your API response to ensure it matches expectations.","cause":"The `userFn` or `loginFn` provided to `configureAuth` is not returning a user object in the expected format (e.g., `{ email: '...' }`), or the API call failed to resolve successfully.","error":"Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'email')"},{"fix":"Ensure that all functions provided to `configureAuth` (e.g., `userFn`, `loginFn`) always return a Promise, even if it's an immediately resolved one like `Promise.resolve(data)`.","cause":"One of the authentication functions (`userFn`, `loginFn`, `registerFn`, `logoutFn`) passed to `configureAuth` did not return a Promise.","error":"Query function returned a non-Promise. Did you forget to 'await' or return a Promise?"}],"ecosystem":"npm"}