This is an automated email from the ASF dual-hosted git repository.
dengliming pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new 8eb1958a fix(SiderMenu): derive flatMenuKeys from current menuData
(#700)
8eb1958a is described below
commit 8eb1958a3c9a966ff5713260e383d552238ad5dd
Author: Revan0809 <[email protected]>
AuthorDate: Thu Oct 1 13:09:57 2026 +0530
fix(SiderMenu): derive flatMenuKeys from current menuData (#700)
SiderMenu cached this.flatMenuKeys in the constructor and never
rebuilt it when the menuData prop changed later (e.g. plugin or
permission menus that populate asynchronously, or a namespace change
introducing new routes). getSelectedMenuKeys() kept matching against
the stale array, so newly-added routes could render but never show as
selected in the sider.
getDefaultCollapsedSubMenus already recomputed a fresh flat-key array
from nextProps.menuData for the open-keys calculation in
getDerivedStateFromProps; getSelectedMenuKeys now does the same by
deriving flatMenuKeys from this.props.menuData on every call instead
of reading a cached instance field.
Fixes #642
---
src/components/SiderMenu/SiderMenu.js | 13 +++++++++----
src/components/SiderMenu/SilderMenu.test.js | 28 +++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/src/components/SiderMenu/SiderMenu.js
b/src/components/SiderMenu/SiderMenu.js
index 54ab0c00..9bcd6619 100644
--- a/src/components/SiderMenu/SiderMenu.js
+++ b/src/components/SiderMenu/SiderMenu.js
@@ -81,9 +81,11 @@ export const getMenuMatchKeys = (flatMenuKeys, paths) =>
export default class SiderMenu extends PureComponent {
constructor(props) {
super(props);
- this.flatMenuKeys = getFlatMenuKeys(props.menuData);
this.state = {
- openKeys: SiderMenu.getDefaultCollapsedSubMenus(props,
this.flatMenuKeys),
+ openKeys: SiderMenu.getDefaultCollapsedSubMenus(
+ props,
+ getFlatMenuKeys(props.menuData),
+ ),
localeName: "",
mode: "inline",
theme: "dark",
@@ -230,11 +232,14 @@ export default class SiderMenu extends PureComponent {
// Get the currently selected menu
getSelectedMenuKeys = () => {
const {
+ menuData,
location: { pathname },
} = this.props;
- // console.log(this.flatMenuKeys, urlToList(pathname));
- return getMenuMatchKeys(this.flatMenuKeys, urlToList(pathname));
+ // Derive flatMenuKeys from the current menuData on every call instead of
+ // caching it, since menuData can change after construction (e.g. plugin
+ // or permission menus that load asynchronously).
+ return getMenuMatchKeys(getFlatMenuKeys(menuData), urlToList(pathname));
};
// conversion Path
diff --git a/src/components/SiderMenu/SilderMenu.test.js
b/src/components/SiderMenu/SilderMenu.test.js
index ac81234f..5e06b2af 100644
--- a/src/components/SiderMenu/SilderMenu.test.js
+++ b/src/components/SiderMenu/SilderMenu.test.js
@@ -16,7 +16,7 @@
*/
import { urlToList } from "../_utils/pathTools";
-import { getFlatMenuKeys, getMenuMatchKeys } from "./SiderMenu";
+import SiderMenu, { getFlatMenuKeys, getMenuMatchKeys } from "./SiderMenu";
const menu = [
{
@@ -87,3 +87,29 @@ describe("test menu match", () => {
).toEqual(["/userinfo", "/userinfo/:id", "/userinfo/:id/info"]);
});
});
+
+describe("SiderMenu#getSelectedMenuKeys", () => {
+ it("matches a route added to menuData after construction", () => {
+ // menuData can be populated asynchronously (e.g. plugin or permission
+ // menus that load after the sider mounts), so the instance must derive
+ // its flattened keys from the current menuData rather than a value
+ // cached at construction time.
+ const instance = new SiderMenu({
+ menuData: menu,
+ location: { pathname: "/dashboard" },
+ });
+
+ instance.props = {
+ menuData: [
+ ...menu,
+ { path: "/plugin", children: [{ path: "/plugin/detail" }] },
+ ],
+ location: { pathname: "/plugin/detail" },
+ };
+
+ expect(instance.getSelectedMenuKeys()).toEqual([
+ "/plugin",
+ "/plugin/detail",
+ ]);
+ });
+});