From 890d3cebf3e2fc1278346a063161c2d6e4c00f76 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Wed, 23 Feb 2022 15:47:12 +0800 Subject: [PATCH] fix: do not fire onRouteUpdate on hash change; new onRouteDidUpdate lifecycle --- packages/docusaurus-types/src/index.d.ts | 8 +++-- .../src/client/PendingNavigation.tsx | 21 ++++++++---- .../client/client-lifecycles-dispatcher.ts | 3 ++ website/_dogfooding/clientModuleExample.ts | 33 +++++++++++++++---- 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 5e9e043ef0ec9..025240c3eecd4 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -451,9 +451,13 @@ export interface TOCItem { export type RouteChunksTree = {[x: string | number]: string | RouteChunksTree}; export type ClientModule = { - onRouteUpdate?: (args: { + onRouteUpdate: (args: { previousLocation: Location | null; location: Location; }) => void; - onRouteUpdateDelayed?: (args: {location: Location}) => void; + onRouteDidUpdate: (args: { + previousLocation: Location | null; + location: Location; + }) => void; + onRouteUpdateDelayed: (args: {location: Location}) => void; }; diff --git a/packages/docusaurus/src/client/PendingNavigation.tsx b/packages/docusaurus/src/client/PendingNavigation.tsx index 050dd1a9000a5..75e5883d4604f 100644 --- a/packages/docusaurus/src/client/PendingNavigation.tsx +++ b/packages/docusaurus/src/client/PendingNavigation.tsx @@ -63,12 +63,12 @@ class PendingNavigation extends React.Component { // Load data while the old screen remains. preload(routes, nextLocation.pathname) .then(() => { - clientLifecyclesDispatcher.onRouteUpdate({ - previousLocation: this.previousLocation, - location: nextLocation, - }); - // Route has loaded, we can reset previousLocation. - this.previousLocation = null; + if (this.previousLocation?.pathname !== nextLocation.pathname) { + clientLifecyclesDispatcher.onRouteUpdate({ + previousLocation: this.previousLocation, + location: nextLocation, + }); + } this.setState({nextRouteHasLoaded: true}, this.stopProgressBar); const {hash} = nextLocation; if (!hash) { @@ -94,6 +94,15 @@ class PendingNavigation extends React.Component { return true; } + componentDidUpdate() { + if (this.previousLocation?.pathname !== this.props.location.pathname) { + clientLifecyclesDispatcher.onRouteDidUpdate({ + previousLocation: this.previousLocation, + location: this.props.location, + }); + } + } + private clearProgressBarTimeout() { if (this.progressBarTimeout) { clearTimeout(this.progressBarTimeout); diff --git a/packages/docusaurus/src/client/client-lifecycles-dispatcher.ts b/packages/docusaurus/src/client/client-lifecycles-dispatcher.ts index 57982c3943138..a90373cd5c398 100644 --- a/packages/docusaurus/src/client/client-lifecycles-dispatcher.ts +++ b/packages/docusaurus/src/client/client-lifecycles-dispatcher.ts @@ -26,6 +26,9 @@ const clientLifecyclesDispatchers: Required = { onRouteUpdate(...args) { dispatchLifecycleAction('onRouteUpdate', args); }, + onRouteDidUpdate(...args) { + dispatchLifecycleAction('onRouteDidUpdate', args); + }, onRouteUpdateDelayed(...args) { dispatchLifecycleAction('onRouteUpdateDelayed', args); }, diff --git a/website/_dogfooding/clientModuleExample.ts b/website/_dogfooding/clientModuleExample.ts index e730f3f3a74e2..94981e6581d06 100644 --- a/website/_dogfooding/clientModuleExample.ts +++ b/website/_dogfooding/clientModuleExample.ts @@ -6,12 +6,33 @@ */ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; +import type {Location} from 'history'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function onRouteUpdate({location}: {location: Location}): void { - // console.log('onRouteUpdate', {location}); +export function onRouteUpdate({ + location, + previousLocation, +}: { + location: Location; + previousLocation: Location; +}): void { + if (ExecutionEnvironment.canUseDOM) { + console.log(`onRouteUpdate (Fired before DOM repaints) +Previous location: ${previousLocation.pathname} +Current location: ${location.pathname} +Current heading: ${document.getElementsByTagName('h1')[0]?.innerText}`); + } } - -if (ExecutionEnvironment.canUseDOM) { - // console.log('client module example log'); +export function onRouteDidUpdate({ + location, + previousLocation, +}: { + location: Location; + previousLocation: Location; +}): void { + if (ExecutionEnvironment.canUseDOM) { + console.log(`onRouteDidUpdate (Fired after DOM repaints) +Previous location: ${previousLocation.pathname} +Current location: ${location.pathname} +Current heading: ${document.getElementsByTagName('h1')[0]?.innerText}`); + } }