{"id":15845,"library":"suspend-react","title":"React Suspense Utilities","description":"suspend-react is a utility library for integrating asynchronous operations seamlessly with React Suspense. It allows developers to define functions that return promises, which then 'suspend' rendering until the promise resolves, effectively bringing an `async/await` like paradigm to React components. The library manages pending and error states at a higher level via React's `<Suspense>` and Error Boundaries, reducing boilerplate in individual components. It features a global, key-based caching mechanism, similar to `useMemo` but with application-wide scope, supporting configurable cache invalidation via `lifespan` and custom equality functions. Additionally, it offers preloading, cache busting, and direct cache peeking utilities. The current stable version is 0.1.3, with recent patch releases in June 2023, indicating a stable yet actively maintained project under the pmndrs umbrella. It simplifies data fetching and resource loading within Suspense-enabled React applications.","status":"active","version":"0.1.3","language":"javascript","source_language":"en","source_url":"https://github.com/pmndrs/suspend-react","tags":["javascript","react","suspense","resource","asset","typescript"],"install":[{"cmd":"npm install suspend-react","lang":"bash","label":"npm"},{"cmd":"yarn add suspend-react","lang":"bash","label":"yarn"},{"cmd":"pnpm add suspend-react","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required peer dependency for React functionality.","package":"react","optional":false}],"imports":[{"note":"suspend-react is an ESM-first package. Use named imports.","wrong":"const suspend = require('suspend-react').suspend","symbol":"suspend","correct":"import { suspend } from 'suspend-react'"},{"note":"Named export for preloading data into the cache.","wrong":"import preload from 'suspend-react'","symbol":"preload","correct":"import { preload } from 'suspend-react'"},{"note":"Named export for clearing cached entries, globally or by specific keys.","wrong":"const clear = require('suspend-react').clear","symbol":"clear","correct":"import { clear } from 'suspend-react'"},{"note":"Named export to access cached values synchronously without suspending.","symbol":"peek","correct":"import { peek } from 'suspend-react'"}],"quickstart":{"code":"import { Suspense } from 'react';\nimport { suspend } from 'suspend-react';\n\nfunction Post({ id, version }) {\n  const data = suspend(async () => {\n    // In a real app, use a more robust fetching mechanism and error handling\n    const res = await fetch(`https://hacker-news.firebaseio.com/${version}/item/${id}.json`);\n    if (!res.ok) {\n      throw new Error(`Failed to fetch post ${id}: ${res.statusText}`);\n    }\n    return res.json();    \n  }, [id, version]);\n\n  return (\n    <div>\n      <h3>{data.title}</h3>\n      <p>by {data.by}</p>\n      <p>Score: {data.score}</p>\n    </div>\n  );\n}\n\nfunction App() {\n  return (\n    <Suspense fallback={<div>Loading post...</div>}>\n      <h1>Hacker News Post</h1>\n      <Post id={8863} version=\"v0\" /> {/* A classic HN post ID */}\n    </Suspense>\n  );\n}\n\n// To run this in a simple environment, you might need a root component:\n// import ReactDOM from 'react-dom/client';\n// const root = ReactDOM.createRoot(document.getElementById('root'));\n// root.render(<App />);","lang":"typescript","description":"Demonstrates basic usage of `suspend` within a React component wrapped by `<Suspense>` to fetch and display data from an asynchronous source, handling loading states declaratively."},"warnings":[{"fix":"Use a robust key generation strategy (e.g., combining IDs, types, and versions) to ensure uniqueness. Consider the scope of your keys when multiple components might use similar data patterns.","message":"The caching mechanism in `suspend-react` operates on a global cache by default. While this simplifies usage, it requires developers to ensure their cache keys are sufficiently unique to prevent unintended conflicts or overwrites if the same keys could logically refer to different data across disparate parts of the application.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Ensure your project uses React version 17.0 or higher to satisfy the peer dependency. Upgrade React if necessary: `npm install react@^17.0 react-dom@^17.0`.","message":"While the README states compatibility with 'React versions >= 16.6', the declared peer dependency is `\"react\": \">=17.0\"`. Installing with React versions 16.x (specifically 16.6-16.9 which introduced Suspense for data fetching) might result in peer dependency warnings or unexpected behavior if certain React 17+ APIs are implicitly relied upon. Always respect the peer dependency range for stable operations.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Always wrap components that use `suspend` (or their parents) in an Error Boundary component to gracefully handle potential runtime errors from asynchronous operations. Example: `<ErrorBoundary><Suspense fallback={...}><MySuspendingComponent /></Suspense></ErrorBoundary>`.","message":"When using `suspend`, errors thrown by the promise-returning function will propagate up to the nearest React Error Boundary. If no Error Boundary is present in the component tree above the suspending component, the application will crash. This is standard React Suspense behavior but a common oversight.","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Wrap the suspending component (or a common ancestor) with `<React.Suspense fallback={<div>Loading...</div>}>` and ensure the `fallback` prop is provided with a valid React element.","cause":"A component using `suspend` rendered without being wrapped by a `<React.Suspense>` component, or the `fallback` prop on `<Suspense>` was omitted.","error":"Error: A component suspended while rendering, but no fallback UI was specified. This means that a 'Suspense' component higher in the tree needs to provide a fallback prop."},{"fix":"Install the package using your package manager: `npm install suspend-react` or `yarn add suspend-react`.","cause":"The `suspend-react` package has not been installed or is not correctly linked in your project.","error":"Module not found: Error: Can't resolve 'suspend-react' in '...' OR Cannot find module 'suspend-react'"},{"fix":"Ensure you are using a named import for `suspend`: `import { suspend } from 'suspend-react';`","cause":"The `suspend` function was either not imported correctly (e.g., attempting a default import or using CommonJS `require` syntax incorrectly) or was not imported at all.","error":"TypeError: suspend is not a function OR suspend is not defined"}],"ecosystem":"npm"}