Skip to content

Graphistry.defaultProps is a no-op under React 19: omitted play becomes play=0, showInfo becomes info=undefined #198

Description

@lmeyerov

Summary

<Graphistry> declares its defaults via Graphistry.defaultProps. React 19 no longer applies defaultProps to function components, so under React 19 every prop the consumer omits arrives as undefined — and several of those are serialized directly into the iframe URL.

The most damaging one is play. A consumer that simply does not pass play gets play=0, which freezes the initial force layout. On a large graph (~25k nodes / 200k edges) the result is an unusable static bubble.

Reproduced against React 19.2 with @graphistry/client-api-react@4.6.6. Still present in the current 5.1.8 — I unpacked the published tarball to confirm before filing.

Mechanism

// v4.6.6 dist/index.cjs.js:8800 / v5.1.8 dist/index.cjs.js:9203
var defaultProps = { ..., play: 5, showInfo: true, showMenu: true, allowFullScreen: true, ... };

// v4.6.6 dist/index.cjs.js:9200 / v5.1.8 dist/index.cjs.js:9600
const playNormalized = typeof play === "boolean" ? play : (play | 0) * 1e3;

// v4.6.6 dist/index.cjs.js:9202 / v5.1.8 dist/index.cjs.js:9608
const url = `${graphistryHost || ""}/graph/graph.html?play=${playNormalized}&info=${showInfo}&splashAfter=${showSplashScreen}&dataset=...`;

// v4.6.6 dist/index.cjs.js:9264 / v5.1.8 dist/index.cjs.js:9665
Graphistry.defaultProps = defaultProps;   // <- ignored by React 19

Under React 19, play === undefined, so undefined | 00play=0.
Likewise showInfo === undefined template-interpolates to the literal string, producing info=undefined in the query string.

Observed vs expected URL

Consumer renders <Graphistry dataset={id} graphistryHost={host} /> with no play and no showInfo.

Under React 18:

https://hub.graphistry.com/graph/graph.html?play=5000&info=true&splashAfter=false&dataset=<id>

Under React 19:

https://hub.graphistry.com/graph/graph.html?play=0&info=undefined&splashAfter=false&dataset=<id>

Other props silently lost the same way

Anything in defaultProps is affected, but these change behavior rather than just cosmetics:

  • allowFullScreen: trueundefined → the iframe is rendered with allowFullScreen={false}.
  • tolerateLoadErrors: true → falsy, changing iframe load-error handling.
  • iframeClassName: "graphistry-iframe" → the iframe loses the class consumers may style against.
  • showMenu / showToolbar / showLoadingIndicator / loadingMessage → the loading placeholder renders without its header/message.

Suggested fix

Replace Graphistry.defaultProps with parameter defaults (or nullish coalescing) inside the component, which works across React 16–19:

const Graphistry = React.forwardRef(({
  play = 5,
  showInfo = true,
  showMenu = true,
  allowFullScreen = true,
  tolerateLoadErrors = true,
  iframeClassName = "graphistry-iframe",
  ...rest
}, ref) => { ... });

Defensively, playNormalized could also guard the coercion so a missing value can never masquerade as an explicit 0:

const playNormalized = typeof play === "boolean" ? play : (Number.isFinite(play) ? play : 5) * 1000;

That distinction matters because play=0 is a legitimate, intentional setting for precomputed / radial / UMAP layouts — so consumers cannot tell "frozen on purpose" from "frozen because a default went missing".

propTypes on function components is likewise deprecated and dropped in React 19, so it may be worth removing in the same pass.

Downstream

Reported in Louie: https://github.com/graphistry/graphistrygpt/issues/3898
Louie-side workaround (restores the dropped defaults at the call site): https://github.com/graphistry/graphistrygpt/pull/3899

We are pinning ^4.6.6 and compensating locally for now. Happy to send a PR here if the parameter-defaults approach looks right to you.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions