ant-design / pro-components

🏆 Use Ant Design like a Pro!
https://pro-components.antdigital.dev
MIT License
4.24k stars 1.35k forks source link

远程加载菜单后,刷新页面后菜单不能保持选中状态🐛[BUG] #331

Closed Bobi-zhou closed 3 years ago

Bobi-zhou commented 4 years ago

🐛 bug 描述

点击一个菜单后,颜色会高亮,但刷新页面后,不能保持刚才选中的菜单高亮

📷 复现步骤

1、启用远程加载菜单数据 2、任意点击一个菜单 3、刷新页面

🏞 期望结果

刷新页面后,依然保持刚才选中的菜单高亮

💻 复现代码

1、安装官方指引创建项目

yarn create umi

选择 ant-design-pro

2、按照官方指引启用远程菜单

  const [menuData, setMenuData] = useState([]);
  useEffect(() => {
    // 这里是一个演示用法
    // 真实项目中建议使用 dva dispatch 或者 umi-request
    fetch('/api/example.json')
      .then(response => response.json())
      .then(data => {
        setMenuData(data || []);
        //console.log(data)
      });
  }, []);

修改ProLayout的menuDataRender

 menuDataRender={()=>menuData}

3、mock数据

export default {
    '/api/example.json': [
        {
          path: '/dashboard',
          name: 'dashboard',
          icon: 'dashboard',
          children: [
            {
              path: '/dashboard/analysis',
              name: 'analysis',
              exact: true,
            },
            {
              path: '/dashboard/monitor',
              name: 'monitor',
              exact: true,
            },
            {
              path: '/dashboard/workplace',
              name: 'workplace',
              exact: true,
            },
          ],
        }
      ]
  };

© 版本信息

🚑 其他信息

刷新前 image 刷新后 image

chenshuai2144 commented 4 years ago

是因为menuRender之后没有重新触发计算导致的

chenshuai2144 commented 4 years ago

https://procomponents.ant.design/components/layout#%E4%BB%8E%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8A%A0%E8%BD%BD-menu

看看这里,无法复现

Bobi-zhou commented 4 years ago

我这边100%复现呢,我的package.json

{
  "name": "ant-design-pro",
  "version": "4.1.0",
  "private": true,
  "description": "An out-of-box UI solution for enterprise applications",
  "scripts": {
    "analyze": "cross-env ANALYZE=1 umi build",
    "build": "umi build",
    "deploy": "npm run site && npm run gh-pages",
    "dev": "npm run start:dev",
    "fetch:blocks": "pro fetch-blocks && npm run prettier",
    "gh-pages": "gh-pages -d dist",
    "i18n-remove": "pro i18n-remove --locale=zh-CN --write",
    "postinstall": "umi g tmp",
    "lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier",
    "lint-staged": "lint-staged",
    "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
    "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style",
    "lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
    "lint:prettier": "prettier --check \"**/*\" --end-of-line auto",
    "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less",
    "prettier": "prettier -c --write \"**/*\"",
    "start": "umi dev",
    "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none umi dev",
    "start:no-mock": "cross-env MOCK=none umi dev",
    "start:no-ui": "cross-env UMI_UI=none umi dev",
    "start:pre": "cross-env REACT_APP_ENV=pre umi dev",
    "start:test": "cross-env REACT_APP_ENV=test MOCK=none umi dev",
    "pretest": "node ./tests/beforeTest",
    "test": "umi test",
    "test:all": "node ./tests/run-tests.js",
    "test:component": "umi test ./src/components",
    "tsc": "tsc"
  },
  "husky": { "hooks": { "pre-commit": "npm run lint-staged" } },
  "lint-staged": {
    "**/*.less": "stylelint --syntax less",
    "**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
    "**/*.{js,jsx,tsx,ts,less,md,json}": ["prettier --write"]
  },
  "browserslist": ["> 1%", "last 2 versions", "not ie <= 10"],
  "dependencies": {
    "@ant-design/icons": "^4.0.0",
    "@ant-design/pro-layout": "^6.0.0",
    "@ant-design/pro-table": "^2.4.0",
    "@antv/data-set": "^0.11.0",
    "@antv/l7-react": "^2.1.9",
    "@types/lodash.debounce": "^4.0.6",
    "@types/lodash.isequal": "^4.5.5",
    "@types/numeral": "^0.0.28",
    "antd": "^4.4.0",
    "bizcharts": "^3.5.3-beta.0",
    "bizcharts-plugin-slider": "^2.1.1-beta.1",
    "classnames": "^2.2.6",
    "dva": "^2.4.0",
    "gg-editor": "^2.0.2",
    "lodash": "^4.17.11",
    "lodash-decorators": "^6.0.0",
    "lodash.debounce": "^4.0.8",
    "lodash.isequal": "^4.5.0",
    "mockjs": "^1.0.1-beta3",
    "moment": "^2.25.3",
    "numeral": "^2.0.6",
    "nzh": "^1.0.3",
    "omit.js": "^1.0.2",
    "path-to-regexp": "2.4.0",
    "prop-types": "^15.5.10",
    "qs": "^6.9.0",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-fittext": "^1.0.0",
    "react-helmet-async": "^1.0.4",
    "react-router": "^4.3.1",
    "umi": "^3.2.0",
    "umi-request": "^1.0.8",
    "use-merge-value": "^1.0.1"
  },
  "devDependencies": {
    "@ant-design/pro-cli": "^1.0.18",
    "@types/classnames": "^2.2.7",
    "@types/express": "^4.17.0",
    "@types/history": "^4.7.2",
    "@types/jest": "^26.0.0",
    "@types/lodash": "^4.14.144",
    "@types/qs": "^6.5.3",
    "@types/react": "^16.9.17",
    "@types/react-dom": "^16.8.4",
    "@types/react-helmet": "^5.0.13",
    "@umijs/fabric": "^2.2.0",
    "@umijs/plugin-blocks": "^2.0.5",
    "@umijs/preset-ant-design-pro": "^1.2.0",
    "@umijs/preset-react": "^1.4.8",
    "@umijs/preset-ui": "^2.0.9",
    "carlo": "^0.9.46",
    "chalk": "^4.0.0",
    "cross-env": "^7.0.0",
    "cross-port-killer": "^1.1.1",
    "detect-installer": "^1.0.1",
    "enzyme": "^3.11.0",
    "eslint": "^7.1.0",
    "express": "^4.17.1",
    "gh-pages": "^3.0.0",
    "husky": "^4.0.7",
    "jsdom-global": "^3.0.2",
    "lint-staged": "^10.0.0",
    "mockjs": "^1.0.1-beta3",
    "prettier": "^2.0.1",
    "pro-download": "1.0.1",
    "puppeteer-core": "^4.0.1",
    "stylelint": "^13.0.0"
  },
  "engines": { "node": ">=10.0.0" },
  "checkFiles": [
    "src/**/*.js*",
    "src/**/*.ts*",
    "src/**/*.less",
    "config/**/*.js*",
    "scripts/**/*.js"
  ],
  "__npminstall_done": false
}
chenshuai2144 commented 4 years ago

方便把你的仓库放上来吗?

Bobi-zhou commented 4 years ago

image

chenshuai2144 commented 4 years ago

来一个 github 的 repo吧,使用mock数据,让我能复现一下

wxf-start commented 4 years ago

来一个 github 的 repo吧,使用mock数据,让我能复现一下

请问你解决了吗,我也遇到了这个问题,刷新以后,选中状态消失了

wxf-start commented 4 years ago

https://procomponents.ant.design/components/layout#%E4%BB%8E%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8A%A0%E8%BD%BD-menu

看看这里,无法复现

我找到不能保持状态的原因了,如果菜单的数据在useEffect里面获取,就会刷新后,无法保持高亮等

chenshuai2144 commented 4 years ago
  useEffect(() => {
    setMenuData([]);
    setLoading(true);
    setTimeout(() => {
      setMenuData(customMenuDate);
      setLoading(false);
    }, 2000);
  }, [index]);

这里也是的

johnnylc commented 4 years ago
  useEffect(() => {
    setMenuData([]);
    setLoading(true);
    setTimeout(() => {
      setMenuData(customMenuDate);
      setLoading(false);
    }, 2000);
  }, [index]);

这里也是的

我测试了下demo,问题可能出在demo中prolayout的menuContentRender的使用上,

 menuContentRender={(_, dom) =>
          loading ? (
            <div
              style={{
                padding: '24px 0',
              }}
            >
              <Spin tip="菜单加载中">{dom}</Spin>
            </div>
          ) : (
            dom
          )
        }

按照demo的代码逻辑:在loading状态时,渲染loading状态的menu节点结构,loading结束后menu节点重新渲染。 如果注释掉menuContentRender中函数,则在更新menuData时问题复现,菜单无法保持选中、展开状态。

测试代码: https://codesandbox.io/s/thirsty-perlman-e51dh?file=/demo.tsx

chenshuai2144 commented 3 years ago

https://beta-pro.ant.design/docs/advanced-menu-cn 这个文档

frank-liu commented 3 years ago

enu节点

@johnnylc 正解。添加menuContentRender属性及其对应的函数即可。

<ProLayout
  // ...
  menuContentRender  = {(_, dom) =>
            !(Array.isArray(menuData) && menuData.length > 0) ? (
              null // 直接返回Null,也可以返回spinner,看各人喜好 <Spin tip="Loading Menu...">{dom}</Spin>
            ) : (
                dom
              )
          }
>
//...
</ProLayout>