Skip to content

Make PendingNavigation.tsx strict-mode-compatible#12310

Draft
seyoon20087 wants to merge 1 commit into
facebook:mainfrom
seyoon20087:pendingnavigation
Draft

Make PendingNavigation.tsx strict-mode-compatible#12310
seyoon20087 wants to merge 1 commit into
facebook:mainfrom
seyoon20087:pendingnavigation

Conversation

@seyoon20087

Copy link
Copy Markdown
Contributor

We found that PendingNavigation.tsx was NOT strict-mode-compatible out of the box.

As shouldComponentUpdate (and thus dispatchLifecycleAction(...)) is double-invoked in development-mode
(when we export StrictMode as default in src/theme/Root.js), this would be a terrible experience during development mode (even though it does not affect production builds).

(For example, the progress bar is still displayed at the top even though navigation was finished because that lifecycle method was double-invoked.)

To address this problem, we use a field this.pendingLocation to track the location that is being preloaded.
During the second synchronous render pass (when StrictMode in development), we compare the nextProps.location against this.pendingLocation and if they match, this returns false immediately, which causes the dispatchLifecycleAction(...) to not run more than one time.

Beyond this fix, this commit also has the added benefit of the following:

Checking if (this.pendingLocation === nextLocation) inside the asynchronous .then() block acts as an abort-and-debounce guard.

If a user rapidly double-clicks different links (e.g., navigating to Page A and then quickly to Page B), the preloading of Page A will resolve but won't trigger state updates or prematurely (for example) dismiss the progress bar for Page B.

NOTE: parts of these code changes and/or the text of this commit were made using AI

Pre-flight checklist

  • I have read the Contributing Guidelines on pull requests.
  • If this is a code change: I have written unit tests and/or added dogfooding pages to fully verify the new behavior.
  • If this is a new API or substantial change: the PR has an accompanying issue (closes #0000) and the maintainers have approved on my working plan.

Motivation

Test Plan

Test links

Deploy preview: https://deploy-preview-_____--docusaurus-2.netlify.app/

Related issues/PRs

Alternate fix for #10037

We found that PendingNavigation.tsx was NOT strict-mode-compatible
out of the box.

As `shouldComponentUpdate` (and thus `dispatchLifecycleAction(...)`)
is double-invoked in development-mode
(when we export StrictMode as default in src/theme/Root.js),
this would be a terrible experience during development mode
(even though it does not affect production builds).

(For example, the progress bar is still displayed at the top
even though navigation was finished because that lifecycle method
was double-invoked.)

To address this problem, we use a field `this.pendingLocation`
to track the location that is being preloaded.
During the second synchronous render pass (when StrictMode in development),
we compare the `nextProps.location` against `this.pendingLocation`
and if they match, this returns `false` immediately,
which causes the `dispatchLifecycleAction(...)` to not run more than one time.

Beyond this fix, this commit also has the added benefit of the following:

Checking `if (this.pendingLocation === nextLocation)` inside the
asynchronous `.then()` block acts as an **abort-and-debounce guard**.

If a user rapidly double-clicks different links
(e.g., navigating to Page A and then quickly to Page B),
the preloading of Page A will resolve
but won't trigger state updates
or prematurely (for example) dismiss the progress bar for Page B.

* NOTE: parts of these code changes
and/or the text of this commit were made using AI

Signed-off-by: seyoon20087 <24852454+seyoon20087@users.noreply.github.com>
@meta-cla meta-cla Bot added the CLA Signed Signed Facebook CLA label Jul 23, 2026
@netlify

netlify Bot commented Jul 23, 2026

Copy link
Copy Markdown

[V2]

Built without sensitive environment variables

Name Link
🔨 Latest commit a867348
🔍 Latest deploy log https://app.netlify.com/projects/docusaurus-2/deploys/6a61d45f852b210007432d2f
😎 Deploy Preview https://deploy-preview-12310--docusaurus-2.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@slorber

slorber commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

We found that PendingNavigation.tsx was NOT strict-mode-compatible out of the box.

How did you find out? We don't have a strict mode setting in Docusaurus (yet). If this is something detected and implemented by AI, please disclose it properly or explain how to reproduce the issues you encountered in a concrete way.

Note that refactoring this without asking me first is not a good idea. We are not even sure to keep this component in v4, see #12201

@seyoon20087

seyoon20087 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

How did you find out?

Sorry about this. First, I created a new site (yarn create docusaurus), and in src/theme/Root.js add these contents:

export { StrictMode as default } from "react";

with the original 'PendingNavigation.tsx', when add that file, this is the video of the demonstration:

Screen.Recording.2026-07-23.at.6.48.26.PM.mov

A progress bar is displayed even though navigation was completed. (I expected that the progress bar isn't displayed)

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

Labels

CLA Signed Signed Facebook CLA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants