Repository: remix-run/react-router
File: packages/react-router-dom/index.tsx (TypeScript)

Code before:

type ViewTransitionContextObject =
  | {
      isTransitioning: false;
    }
  | {
      isTransitioning: true;
      currentLocation: Location;
      nextLocation: Location;
    };

const ViewTransitionContext = React.createContext<ViewTransitionContextObject>({
  isTransitioning: false,
});
if (__DEV__) {
  ViewTransitionContext.displayName = "ViewTransition";
}

export { ViewTransitionContext as UNSAFE_ViewTransitionContext };

//#endregion

////////////////////////////////////////////////////////////////////////////////
//#region Components
////////////////////////////////////////////////////////////////////////////////

/**
  Webpack + React 17 fails to compile on any of the following because webpack
  complains that `startTransition` doesn't exist in `React`:
  * import { startTransition } from "react"
  * import * as React from from "react";
    "startTransition" in React ? React.startTransition(() => setState()) : setState()
  * import * as React from from "react";
    "startTransition" in React ? React["startTransition"](() => setState()) : setState()

  Moving it to a constant such as the following solves the Webpack/React 17 issue:
  * import * as React from from "react";
    const START_TRANSITION = "startTransition";
    START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()

  However, that introduces webpack/terser minification issues in production builds
  in React 18 where minification/obfuscation ends up removing the call of
  React.startTransition entirely from the first half of the ternary.  Grabbing
  this exported reference once up front resolves that issue.

  See https://github.com/remix-run/react-router/issues/10579
*/
const START_TRANSITION = "startTransition";
const startTransitionImpl = React[START_TRANSITION];

function startTransitionSafe(cb: () => void) {

Review comment (suggestion):
Fetcher data lives in the React layer now, and we use ref counting via `register`/`unregister` to know when to remove from `fetcherData`

Code after:

type ViewTransitionContextObject =
  | {
      isTransitioning: false;
    }
  | {
      isTransitioning: true;
      currentLocation: Location;
      nextLocation: Location;
    };

const ViewTransitionContext = React.createContext<ViewTransitionContextObject>({
  isTransitioning: false,
});
if (__DEV__) {
  ViewTransitionContext.displayName = "ViewTransition";
}

export { ViewTransitionContext as UNSAFE_ViewTransitionContext };

// TODO: (v7) Change the useFetcher data from `any` to `unknown`
type FetchersContextObject = {
  fetcherData: Map<string, any>;
  register: (key: string) => void;
  unregister: (key: string) => void;
};

const FetchersContext = React.createContext<FetchersContextObject | null>(null);
if (__DEV__) {
  FetchersContext.displayName = "Fetchers";
}

export { FetchersContext as UNSAFE_FetchersContext };

//#endregion

////////////////////////////////////////////////////////////////////////////////
//#region Components
////////////////////////////////////////////////////////////////////////////////

/**
  Webpack + React 17 fails to compile on any of the following because webpack
  complains that `startTransition` doesn't exist in `React`:
  * import { startTransition } from "react"
  * import * as React from from "react";
    "startTransition" in React ? React.startTransition(() => setState()) : setState()
  * import * as React from from "react";
    "startTransition" in React ? React["startTransition"](() => setState()) : setState()

  Moving it to a constant such as the following solves the Webpack/React 17 issue:
  * import * as React from from "react";