使用ant-design-pro模板。 https://github.com/ant-design...
想實(shí)現(xiàn)從后臺(tái)請(qǐng)求菜單數(shù)據(jù),數(shù)據(jù)可以正確獲取,并且state改變也是正確的,但是在頁(yè)面渲染的時(shí)候,并不能將數(shù)據(jù)加載到菜單組件中。
獲取菜單數(shù)據(jù)部分,我是寫入componentWillMount函數(shù)中。
class BasicLayout extends React.PureComponent {
……
componentWillMount() {
const { dispatch } = this.props;
dispatch({
type: 'user/fetchMenu',
});
}
……
}
但是再次進(jìn)行登錄,由于state中已經(jīng)有了菜單數(shù)據(jù),所以可以正確加載菜單以及數(shù)據(jù)。
我注意到BasicLayout這個(gè)大的組件和SideMenu這兩個(gè)組件都是使用PureComponent,不知是否和這個(gè)相關(guān)?
// 請(qǐng)把代碼文本粘貼到下方(請(qǐng)勿用圖片代替代碼)
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { Icon, Layout, message } from 'antd';
import DocumentTitle from 'react-document-title';
import { connect } from 'dva';
import { Redirect, Route, routerRedux, Switch } from 'dva/router';
import { ContainerQuery } from 'react-container-query';
import classNames from 'classnames';
import pathToRegexp from 'path-to-regexp';
import { enquireScreen, unenquireScreen } from 'enquire-js';
import GlobalHeader from '../components/GlobalHeader';
import GlobalFooter from '../components/GlobalFooter';
import SiderMenu from '../components/SiderMenu';
import NotFound from '../routes/Exception/404';
import { getRoutes } from '../utils/utils';
import Authorized from '../utils/Authorized';
import { getMenuData } from '../common/menu';
import logo from '../assets/logo.svg';
const { Content, Header, Footer } = Layout;
const { AuthorizedRoute, check } = Authorized;
/**
* 根據(jù)菜單取得重定向地址.
*/
const redirectData = [];
const getRedirect = item => {
if (item && item.children) {
if (item.children[0] && item.children[0].path) {
redirectData.push({
from: `${item.path}`,
to: `${item.children[0].path}`,
});
item.children.forEach(children => {
getRedirect(children);
});
}
}
};
getMenuData().forEach(getRedirect);
/**
* 獲取面包屑映射
* @param {Object} menuData 菜單配置
* @param {Object} routerData 路由配置
*/
const getBreadcrumbNameMap = (menuData, routerData) => {
const result = {};
const childResult = {};
for (const i of menuData) {
if (!routerData[i.path]) {
result[i.path] = i;
}
if (i.children) {
Object.assign(childResult, getBreadcrumbNameMap(i.children, routerData));
}
}
return Object.assign({}, routerData, result, childResult);
};
const query = {
'screen-xs': {
maxWidth: 575,
},
'screen-sm': {
minWidth: 576,
maxWidth: 767,
},
'screen-md': {
minWidth: 768,
maxWidth: 991,
},
'screen-lg': {
minWidth: 992,
maxWidth: 1199,
},
'screen-xl': {
minWidth: 1200,
maxWidth: 1599,
},
'screen-xxl': {
minWidth: 1600,
},
};
let isMobile;
enquireScreen(b => {
isMobile = b;
});
class BasicLayout extends React.Component {
static childContextTypes = {
location: PropTypes.object,
breadcrumbNameMap: PropTypes.object,
};
state = {
isMobile,
};
getChildContext() {
const { location, routerData, menu } = this.props;
return {
location,
breadcrumbNameMap: getBreadcrumbNameMap(menu, routerData), // getMenuData()
};
}
componentWillMount() {
const { dispatch } = this.props;
dispatch({
type: 'user/fetchMenu',
});
}
componentDidMount() {
this.enquireHandler = enquireScreen(mobile => {
this.setState({
isMobile: mobile,
});
});
const { dispatch } = this.props;
dispatch({
type: 'user/fetchCurrent',
});
}
componentWillUnmount() {
unenquireScreen(this.enquireHandler);
}
getPageTitle() {
const { routerData, location } = this.props;
const { pathname } = location;
let title = '沃協(xié)同';
let currRouterData = null;
// match params path
Object.keys(routerData).forEach(key => {
if (pathToRegexp(key).test(pathname)) {
currRouterData = routerData[key];
}
});
if (currRouterData && currRouterData.name) {
title = `${currRouterData.name} - 沃協(xié)同`;
}
return title;
}
getBaseRedirect = () => {
// According to the url parameter to redirect
// 這里是重定向的,重定向到 url 的 redirect 參數(shù)所示地址
const urlParams = new URL(window.location.href);
const redirect = urlParams.searchParams.get('redirect');
// Remove the parameters in the url
if (redirect) {
urlParams.searchParams.delete('redirect');
window.history.replaceState(null, 'redirect', urlParams.href);
} else {
const { routerData } = this.props;
// get the first authorized route path in routerData
const authorizedPath = Object.keys(routerData).find(
item => check(routerData[item].authority, item) && item !== '/'
);
return authorizedPath;
}
return redirect;
};
handleMenuCollapse = collapsed => {
const { dispatch } = this.props;
dispatch({
type: 'global/changeLayoutCollapsed',
payload: collapsed,
});
};
handleNoticeClear = type => {
message.success(`清空了${type}`);
const { dispatch } = this.props;
dispatch({
type: 'global/clearNotices',
payload: type,
});
};
handleMenuClick = ({ key }) => {
const { dispatch } = this.props;
if (key === 'triggerError') {
dispatch(routerRedux.push('/exception/trigger'));
return;
}
if (key === 'logout') {
dispatch({
type: 'login/logout',
});
}
};
handleNoticeVisibleChange = visible => {
const { dispatch } = this.props;
if (visible) {
dispatch({
type: 'global/fetchNotices',
});
}
};
render() {
const {
currentUser,
collapsed,
fetchingNotices,
notices,
routerData,
match,
location,
menu,
} = this.props;
const { isMobile: mb } = this.state;
const bashRedirect = this.getBaseRedirect();
const layout = (
<Layout>
<SiderMenu
logo={logo}
// 不帶Authorized參數(shù)的情況下如果沒有權(quán)限,會(huì)強(qiáng)制跳到403界面
// If you do not have the Authorized parameter
// you will be forced to jump to the 403 interface without permission
Authorized={Authorized}
menuData={menu} // JSON.parse(localStorage.getItem('menu'))
collapsed={collapsed}
location={location}
isMobile={mb}
onCollapse={this.handleMenuCollapse}
/>
<Layout>
<Header style={{ padding: 0 }}>
<GlobalHeader
logo={logo}
currentUser={currentUser}
fetchingNotices={fetchingNotices}
notices={notices}
collapsed={collapsed}
isMobile={mb}
onNoticeClear={this.handleNoticeClear}
onCollapse={this.handleMenuCollapse}
onMenuClick={this.handleMenuClick}
onNoticeVisibleChange={this.handleNoticeVisibleChange}
/>
</Header>
<Content style={{ margin: '24px 24px 0', height: '100%' }}>
<Switch>
{redirectData.map(item => (
<Redirect key={item.from} exact from={item.from} to={item.to} />
))}
{getRoutes(match.path, routerData).map(item => (
<AuthorizedRoute
key={item.key}
path={item.path}
component={item.component}
exact={item.exact}
authority={item.authority}
redirectPath="/exception/403"
/>
))}
<Redirect exact from="/" to={bashRedirect} />
<Route render={NotFound} />
</Switch>
</Content>
<Footer style={{ padding: 0 }}>
<GlobalFooter
links={[
{
key: 'Jenkins',
title: 'Jenkins',
href: 'http://10.124.210.64:8080',
blankTarget: true,
},
{
key: 'gitlab',
title: <Icon type="gitlab" />,
href: 'http://10.124.210.40:8080/',
blankTarget: true,
},
{
key: 'Marathon',
title: 'Marathon',
href: 'http://10.124.210.41:8080/ui/#/apps',
blankTarget: true,
},
]}
copyright={
<Fragment>
Copyright <Icon type="copyright" /> 2018 聯(lián)通系統(tǒng)集成-沃協(xié)同項(xiàng)目組
</Fragment>
}
/>
</Footer>
</Layout>
</Layout>
);
return (
<DocumentTitle title={this.getPageTitle()}>
<ContainerQuery query={query}>
{params => <div className={classNames(params)}>{layout}</div>}
</ContainerQuery>
</DocumentTitle>
);
}
}
function mapStateToProps(state) {
return {
...state,
menu: state.user.menu,
currentUser: state.user.currentUser,
collapsed: state.global.collapsed,
fetchingNotices: state.loading.effects['global/fetchNotices'],
notices: state.global.notices,
};
}
export default connect(mapStateToProps)(BasicLayout);
官網(wǎng)建議獲取數(shù)據(jù)的api,放在componentDidMount 生命周期中,且在16.4.1版本貌似 componentWillMount生命周期已經(jīng)被廢除, 你可以確定下 <SiderMenu
logo={logo}
// 不帶Authorized參數(shù)的情況下如果沒有權(quán)限,會(huì)強(qiáng)制跳到403界面
// If you do not have the Authorized parameter
// you will be forced to jump to the 403 interface without permission
Authorized={Authorized}
menuData={menu} // JSON.parse(localStorage.getItem('menu'))
collapsed={collapsed}
location={location}
isMobile={mb}
onCollapse={this.handleMenuCollapse}
/>
這段代碼是否獲取到了menu的值
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過(guò)二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。