Skip to content

Commit df93c1c

Browse files
authored
Merge pull request #2935 from headlamp-k8s/sidebar-memo-fix
frontend: Fix incorrect links in sidebar after switching clusters
2 parents 2fcfc02 + 4e1da88 commit df93c1c

File tree

3 files changed

+20
-14
lines changed

3 files changed

+20
-14
lines changed

frontend/src/components/App/TopBar.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { has } from 'lodash';
1313
import React, { memo, useCallback } from 'react';
1414
import { useTranslation } from 'react-i18next';
1515
import { useDispatch } from 'react-redux';
16-
import { useHistory } from 'react-router-dom';
16+
import { useHistory, useLocation } from 'react-router-dom';
1717
import helpers from '../../helpers';
1818
import { getToken, setToken } from '../../lib/auth';
1919
import { useCluster, useClustersConf } from '../../lib/k8s';
@@ -71,6 +71,10 @@ export default function TopBar({}: TopBarProps) {
7171
const history = useHistory();
7272
const { appBarActions, appBarActionsProcessors } = useAppBarActionsProcessed();
7373

74+
// getToken may return stale value so we need to rerender on navigation
75+
// TODO: create a useToken hook that always returns latest token
76+
// eslint-disable-next-line no-unused-vars
77+
const _location = useLocation();
7478
function hasToken() {
7579
return !!cluster ? !!getToken(cluster) : false;
7680
}

frontend/src/components/Sidebar/SidebarItem.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import ListItem, { ListItemProps } from '@mui/material/ListItem';
44
import { useTheme } from '@mui/system';
55
import React, { memo } from 'react';
66
import { generatePath } from 'react-router';
7+
import { useCluster } from '../../lib/k8s';
78
import { createRouteURL, getRoute } from '../../lib/router';
8-
import { getCluster, getClusterPrefixedPath } from '../../lib/util';
9+
import { getClusterPrefixedPath } from '../../lib/util';
910
import ListItemLink from './ListItemLink';
1011
import { SidebarEntry } from './sidebarSlice';
1112

@@ -45,12 +46,13 @@ const SidebarItem = memo((props: SidebarItemProps) => {
4546
} = props;
4647
const hasSubtitle = !!subtitle;
4748
const theme = useTheme();
49+
const cluster = useCluster();
4850

4951
// const classes = useItemStyle({ fullWidth, hasSubtitle: !!subtitle });
5052

5153
let fullURL = url;
52-
if (fullURL && useClusterURL && getCluster()) {
53-
fullURL = generatePath(getClusterPrefixedPath(url), { cluster: getCluster()! });
54+
if (fullURL && useClusterURL && cluster) {
55+
fullURL = generatePath(getClusterPrefixedPath(url), { cluster });
5456
}
5557

5658
if (!fullURL) {

frontend/src/lib/k8s/index.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import _ from 'lodash';
22
import React, { useMemo } from 'react';
3-
import { matchPath, useLocation } from 'react-router-dom';
3+
import { matchPath, useHistory } from 'react-router-dom';
44
import { ConfigState } from '../../redux/configSlice';
55
import { useTypedSelector } from '../../redux/reducers/reducers';
66
import { getCluster, getClusterGroup, getClusterPrefixedPath } from '../util';
@@ -106,15 +106,13 @@ export function useClustersConf(): ConfigState['allClusters'] {
106106
}
107107

108108
export function useCluster() {
109-
// Make sure we update when changing clusters.
110-
// @todo: We need a better way to do this.
111-
const location = useLocation();
109+
const history = useHistory();
112110

113111
// This function is similar to the getCluster() but uses the location
114112
// meaning it will return the URL from whatever the router used it (which
115113
// is more accurate than getting it from window.location like the former).
116114
function getClusterFromLocation(): string | null {
117-
const urlPath = location?.pathname;
115+
const urlPath = history.location?.pathname;
118116
const clusterURLMatch = matchPath<{ cluster?: string }>(urlPath, {
119117
path: getClusterPrefixedPath(),
120118
});
@@ -124,11 +122,13 @@ export function useCluster() {
124122
const [cluster, setCluster] = React.useState<string | null>(getClusterFromLocation());
125123

126124
React.useEffect(() => {
127-
const currentCluster = getClusterFromLocation();
128-
if (cluster !== currentCluster) {
129-
setCluster(currentCluster);
130-
}
131-
}, [cluster, location]);
125+
// Listen to route changes
126+
return history.listen(() => {
127+
const newCluster = getClusterFromLocation();
128+
// Update the state only when the cluster changes
129+
setCluster(currentCluster => (newCluster !== currentCluster ? newCluster : currentCluster));
130+
});
131+
}, [history]);
132132

133133
return cluster;
134134
}

0 commit comments

Comments
 (0)