facebook/react · error · Error

react-cache: read and preload may only be called from within

Error message

react-cache: read and preload may only be called from within a component's render. They are not supported in event handlers or lifecycle methods.

What it means

react-cache's read() and preload() ultimately call readContext, which uses React's current dispatcher (SharedInternals.H). That dispatcher only exists while a component is rendering; outside render it is null, and readContext throws to tell you these APIs are render-only. The message spells out the contract: read and preload are for component render, not event handlers or lifecycle methods.

Source

Thrown at packages/react-cache/src/ReactCacheOld.js:55

type Resource<I, V> = {
  read(I): V,
  preload(I): void,
  ...
};

const Pending = 0;
const Resolved = 1;
const Rejected = 2;

const SharedInternals =
  React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;

function readContext(Context: ReactContext<mixed>) {
  const dispatcher = SharedInternals.H;
  if (dispatcher === null) {
    // This wasn't being minified but we're going to retire this package anyway.
    // eslint-disable-next-line react-internal/prod-error-codes
    throw new Error(
      'react-cache: read and preload may only be called from within a ' +
        "component's render. They are not supported in event handlers or " +
        'lifecycle methods.',
    );
  }
  return dispatcher.readContext(Context);
}

// $FlowFixMe[missing-local-annot]
function identityHashFn(input) {
  if (__DEV__) {
    if (
      typeof input !== 'string' &&
      typeof input !== 'number' &&
      typeof input !== 'boolean' &&
      input !== undefined &&
      input !== null
    ) {

View on GitHub (pinned to eafeac097b)

Solutions

  1. Call read/preload only during render of a component (the same rule as hooks)
  2. For event-handler data needs, use your data layer directly (fetch, query client, framework cache) instead of react-cache
  3. For prefetch-on-interaction, call your framework's prefetch API, or set state that renders a component which then calls preload during render
  4. Migrate off react-cache to a maintained cache (framework data caching) - the package is scheduled for retirement

Example fix

// before
function Button() {
  return <button onClick={() => {
    const data = cache.read(key); // outside render -> throws
  }}>Load</button>;
}

// after
function Panel() {
  const data = cache.read(key); // during render, suspends as designed
  return <div>{data}</div>;
}
Defensive patterns

Strategy: validation

Validate before calling

// Render-phase check mirroring the library's own invariant
import * as React from 'react';

const clientInternals = (React as any)
  .__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const isInRender = () => clientInternals != null && clientInternals.H !== null;

// guard:
if (!isInRender()) {
  throw new Error('cache.read called outside render - move it into a component');
}

Prevention

When it happens

Trigger: Calling cache.read(...) or cache.preload(...) from an event handler (onClick), from useEffect/useLayoutEffect, from a class lifecycle method (componentDidMount), from setTimeout/module scope, or from a Server Component context where no client dispatcher is present.

Common situations: Moving a read into an effect to 'avoid Suspense flicker'; prefetching on hover by calling preload in an event handler; calling cache APIs from a store or router hook that runs outside React's render phase; also note react-cache is a deprecated/unmaintained package, so newer React internals make this easier to hit.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/5dab03e51760b8a4. Report an issue: GitHub.