{"id":11921,"library":"redux-query-react","title":"Redux Query React Integration","description":"redux-query-react provides the React-specific interface for integrating with redux-query, a library designed for managing network state within Redux applications. It streamlines the process of fetching data, handling optimistic updates, and managing cancellations directly from React components. The current stable release candidate is `3.6.1-rc.2`, indicating active development with ongoing release candidates. While a precise release cadence isn't specified, the project exhibits a feature-driven release model. Key differentiators include its adherence to core Redux principles (middleware, actions, selectors, reducers), ensuring minimal 'magic' and high extensibility, allowing for custom middleware, UI integrations, and network interfaces. It offers both modern React hooks (like `useRequest`, `useMutation`) and higher-order components (`connectRequest`) to colocate data dependencies with components and trigger requests on mount or update, working seamlessly with both functional and class components.","status":"active","version":"3.6.1-rc.2","language":"javascript","source_language":"en","source_url":"https://github.com/amplitude/redux-query","tags":["javascript","redux-query","redux","react","query","fetch","REST","typescript"],"install":[{"cmd":"npm install redux-query-react","lang":"bash","label":"npm"},{"cmd":"yarn add redux-query-react","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-query-react","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for building user interfaces with React components and hooks.","package":"react","optional":false},{"reason":"Provides the Provider component and hooks to connect React components to the Redux store.","package":"react-redux","optional":false},{"reason":"The core library for network state management that redux-query-react integrates with.","package":"redux-query","optional":false}],"imports":[{"note":"Primary hook for declaratively fetching data based on component lifecycle. The library primarily uses named exports.","wrong":"const useRequest = require('redux-query-react').useRequest;","symbol":"useRequest","correct":"import { useRequest } from 'redux-query-react';"},{"note":"Primary hook for performing data mutations (e.g., POST, PUT, DELETE) with optional optimistic updates. This is a named export.","wrong":"import useMutation from 'redux-query-react';","symbol":"useMutation","correct":"import { useMutation } from 'redux-query-react';"},{"note":"Higher-Order Component (HOC) for integrating data dependencies with class components or pre-hooks functional components. Ships with TypeScript types for HOCs and hooks.","wrong":"const connectRequest = require('redux-query-react').connectRequest;","symbol":"connectRequest","correct":"import { connectRequest } from 'redux-query-react';"}],"quickstart":{"code":"import React from 'react';\nimport { createStore, combineReducers, applyMiddleware } from 'redux';\nimport { Provider } from 'react-redux';\nimport { queriesReducer, queriesMiddleware, QueryConfig } from 'redux-query';\nimport { useRequest, useMutation } from 'redux-query-react';\nimport { createNetworkHandler } from 'redux-query-interface-superagent'; // For a real app, install this\n\n// A mock network handler for demonstration purposes\nconst mockNetworkHandler = createNetworkHandler({\n  adapter: (config) => {\n    console.log('Mock API call:', config.url, config.method, config.body);\n    return new Promise((resolve, reject) => {\n      setTimeout(() => {\n        if (config.url === '/api/users/1') {\n          resolve({\n            status: 200,\n            body: { id: 1, name: 'Alice', email: 'alice@example.com' },\n            headers: new Headers(),\n          });\n        } else if (config.url === '/api/users/1' && config.method === 'PUT') {\n          resolve({\n            status: 200,\n            body: { id: 1, name: config.body.name, email: 'alice@example.com' },\n            headers: new Headers(),\n          });\n        } else {\n          reject({ status: 404, body: 'Not Found', headers: new Headers() });\n        }\n      }, 500);\n    });\n  }\n});\n\n// Setup Redux store with redux-query\nconst rootReducer = combineReducers({\n  queries: queriesReducer,\n  // Add other reducers here\n});\n\nconst store = createStore(\n  rootReducer,\n  applyMiddleware(queriesMiddleware(mockNetworkHandler))\n);\n\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\n// Define a query config for fetching a user\nconst getUserQuery: QueryConfig = {\n  url: '/api/users/1',\n  update: {\n    entities: (prevEntities: any = {}, newEntities: any) => ({\n      ...prevEntities,\n      user: newEntities.user, // Assuming API returns { user: { ... } }\n    }),\n  },\n  // Map the query response data to a specific key, if needed.\n  // data: (queryState) => queryState.entities.user\n};\n\nconst UserProfile: React.FC = () => {\n  // Use useRequest to fetch user data\n  const { isPending, isFinished, data } = useRequest<User>(getUserQuery);\n\n  // Use useMutation to update user data with optimistic updates\n  const [updateUserName, { isPending: isUpdatingName }] = useMutation(\n    (newName: string) => ({\n      url: '/api/users/1',\n      method: 'PUT',\n      body: { name: newName },\n      update: {\n        entities: (prevEntities: any = {}, newEntities: any) => ({\n          ...prevEntities,\n          user: newEntities.user,\n        }),\n      },\n      optimistic: {\n        entities: (prevEntities: any = {}) => ({\n          ...prevEntities,\n          user: { ...prevEntities.user, name: newName + ' (optimistic)' },\n        }),\n      },\n    })\n  );\n\n  const handleRenameUser = () => {\n    updateUserName('Bob');\n  };\n\n  if (isPending) return <div>Loading user profile...</div>;\n  if (!data) return <div>No user data available.</div>;\n\n  return (\n    <div>\n      <h2>User Profile</h2>\n      <p>ID: {data.id}</p>\n      <p>Name: {data.name} {isUpdatingName && '(Updating...)'}</p>\n      <p>Email: {data.email}</p>\n      <button onClick={handleRenameUser} disabled={isUpdatingName}>Rename to Bob</button>\n    </div>\n  );\n};\n\nconst App: React.FC = () => (\n  <Provider store={store}>\n    <UserProfile />\n  </Provider>\n);\n\nexport default App;\n","lang":"typescript","description":"This example demonstrates how to set up a Redux store with `redux-query`, define a `networkHandler` (mocked here), and use `redux-query-react`'s `useRequest` hook to fetch and display user data, along with `useMutation` for optimistic updates on a user's name."},"warnings":[{"fix":"Refer to the `redux-query` v2 transition guide for detailed migration steps, focusing on `networkHandler` implementation and revised mutation configurations. This includes updates to how network requests are defined and how optimistic updates and rollbacks are handled.","message":"Major architectural changes in `redux-query` v2 required significant upgrades. The `request` fields in the `queries` reducer and actions were replaced with `networkHandler`, and rollback behavior for mutations was updated. Users migrating from `1.x` to `2.x` must consult the v2 transition guide for `redux-query`.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure your project's `react-redux` and `redux-query` versions precisely match or are compatible with the peer dependency ranges specified in `redux-query-react`'s `package.json`. Use `npm install --legacy-peer-deps` or `yarn add --peer-deps-strict false` if you encounter peer dependency warnings and are confident in compatibility, but verify thoroughly.","message":"`redux-query-react` has specific peer dependency requirements, notably for `react-redux@7.1.0` and `redux-query@^3.0.0-alpha.10`. Mismatches with these versions can lead to runtime errors or unexpected behavior due to API changes in these core libraries.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If upgrading Redux to v4+, ensure `redux-query-react` is at least `v2.3.1`. Review Redux's official migration guides for any breaking changes related to `createStore`, middleware, or enhancers, in addition to `redux-query-react`'s specific updates.","message":"While `redux-query-react` gained support for Redux v4 in `v2.3.1`, upgrading Redux itself in your application may introduce other breaking changes or require adjustments in your Redux store configuration outside of `redux-query`.","severity":"gotcha","affected_versions":"Prior to v2.3.1 if using Redux v4. From v2.3.1 onward, potential Redux-specific migration challenges."},{"fix":"Update mutation configurations to leverage the new `rollback` option and review how optimistic updates interact with failure scenarios to ensure desired behavior. Consult the `redux-query` v2 transition guide for details on the new rollback mechanism.","message":"`redux-query` v2 introduced new, safer rollback behavior when mutations fail, along with a `rollback` option in query configs. Developers relying on optimistic updates in earlier versions might need to adjust their mutation logic to account for these changes.","severity":"breaking","affected_versions":"<2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `useRequest` and `useMutation` are only invoked directly within the top level of a functional component or a custom hook that follows React's rules for calling hooks.","cause":"`useRequest` or `useMutation` is being called outside of a React functional component or a custom hook that adheres to React's rules of hooks.","error":"Error: Invariant Violation: Hooks can only be called inside of the body of a function component."},{"fix":"Verify that `queriesReducer` is added to your root reducer and `queriesMiddleware` is applied to your Redux store. Ensure the top-level component that uses `redux-query-react` hooks or HOCs is rendered inside a `react-redux` `<Provider>` component.","cause":"The `redux-query` middleware or reducer is not correctly integrated into your Redux store, or your React components are not wrapped within a `<Provider store={store}>` from `react-redux`.","error":"Invariant Violation: Could not find `store` in the context of `<Connect(Component)>`"},{"fix":"Run `npm install redux-query-react` or `yarn add redux-query-react` to install the package. Double-check your import statements for any typos in the package name or path.","cause":"The `redux-query-react` package is not installed in your project, or there is a typo in the import path.","error":"Module not found: Error: Can't resolve 'redux-query-react' in '...'"}],"ecosystem":"npm"}