-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(catalog): introduce usePathname hook, remove React Router de…
…pendency from the Catalog (#1276) **Related Ticket:** Contributes to #1108 ### Description of Changes - Remove `react-router` dependency from the Catalog components - Introduce custom `usePathname` hook - Remove prop drilling of pathname from the Catalog ### Notes & Questions About Changes The `pathname` prop is passed down for two things: 1. Generating a link to the dataset at https://github.com/NASA-IMPACT/veda-ui/blob/820730fd7c1e25e68997b200d31bc4ee27525f7e/app/scripts/components/common/catalog/catalog-card.tsx#L126 2. Controlling scroll in the filters control at https://github.com/NASA-IMPACT/veda-ui/blob/820730fd7c1e25e68997b200d31bc4ee27525f7e/app/scripts/components/common/catalog/filters-control.tsx#L57 I suspect that the usage on item 1 was intented to cover the use case of an instance running on a subpath (e.g. `https://myinstance.org/veda`), why is hard to replicate locally but this change shouldn't affect that. ### Validation / Testing Using `veda-config`: 1. Visit the data catalog page 1. Clicking on cards should open the proper URL (same as before) 1. Visit Explorer page, clicking on cards selected them, instead of visiting an URL (same as before) Using `next-veda-ui` instance: 1. Link the source of this PR to the Next.js instance 1. Visit the catalog page 1. Clicking on cards should open the proper URL (same as before) 1. Visit Explorer page, clicking on cards selected them, instead of visiting an URL (same as before) This is ready for review.
- Loading branch information
Showing
7 changed files
with
66 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { useEffect, useState } from 'react'; | ||
|
||
/** | ||
* usePathname | ||
* * | ||
* This hook is implemented to work in both client-side rendering | ||
* and server-side rendering environments. During SSR, it initializes the | ||
* `pathname` as an empty string, ensuring the application remains stable in | ||
* non-browser environments. | ||
* | ||
* @returns {string} The current `pathname`. Returns an empty string during SSR | ||
* or if the `window` object is unavailable. | ||
*/ | ||
export const usePathname = () => { | ||
const [pathname, setPathname] = useState( | ||
typeof window !== 'undefined' ? window.location.pathname : '' | ||
); | ||
|
||
useEffect(() => { | ||
if (typeof window === 'undefined') return; | ||
|
||
const updatePathname = () => { | ||
setPathname(window.location.pathname); | ||
}; | ||
|
||
// Listen to popstate events (back/forward navigation) | ||
window.addEventListener('popstate', updatePathname); | ||
|
||
// Detect programmatic navigation by dispatching a custom event | ||
const originalPushState = history.pushState; | ||
const originalReplaceState = history.replaceState; | ||
|
||
const customEvent = new Event('pathnamechange'); | ||
const dispatchPathnameChange = () => { | ||
window.dispatchEvent(customEvent); | ||
}; | ||
|
||
history.pushState = function (...args) { | ||
originalPushState.apply(this, args); | ||
dispatchPathnameChange(); | ||
}; | ||
|
||
history.replaceState = function (...args) { | ||
originalReplaceState.apply(this, args); | ||
dispatchPathnameChange(); | ||
}; | ||
|
||
window.addEventListener('pathnamechange', updatePathname); | ||
|
||
return () => { | ||
window.removeEventListener('popstate', updatePathname); | ||
window.removeEventListener('pathnamechange', updatePathname); | ||
history.pushState = originalPushState; | ||
history.replaceState = originalReplaceState; | ||
}; | ||
}, []); | ||
|
||
return pathname; | ||
}; |