在使用react-router-dom时出现了问题,我将Link封装到一个左侧导航菜单中,然后把路由封装到另外一个组建中,在封装的时候没有注意到Router只能配置一个,导致在点击左侧导航栏时,url发生变化,并没有匹配到Route中的path,从而导致没有重新渲染组件。
在最外层配置一个总的Router:
import React, { Component } from 'react';
import { Badge, Breadcrumb, Icon, Input, InputNumber, Layout, Menu, Select } from 'antd';
import { BrowserRouter as Router } from 'react-router-dom'
import 'antd/dist/antd.css';
import '../../assets/css/App.css'
import '../../assets/css/main.css'
import logo from '../../assets/images/company_logo.png'
import ContentRouter from '../../components/routes/ContentRouter'
import SidebarConst from '../../components/sidebar/SidebarConst';
Layout.Header.background = "white";
const { Header, Content, Sider, Footer } = Layout;
const { Option } = Select;
class Index extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<Router>
<div>
<div style={{ width: '100%', height: "1200" }}>
<Layout>
<Header style={{ background: '#3680C1', verticalAlign: "middle", height: "60px" }}>
<div style={{ fload: "left", height: "100%" }}>
<div style={{ display: 'inline', paddingTop: '5px', paddingRight: '15px', height: "60px" }}>
<img src={logo} alt="HAM-NG" style={{ dispaly: "block", marginLeft: 0, marginTop: "auto" }}></img>
</div>
<div style={{ display: 'inline', color: 'white', verticalAlign: "middle" }}>HAM-NG管理平台</div>
<div style={{ display: 'inline', float: 'right', verticalAlign: 'middle' }}>
<Badge count={99} style={{ paddingLeft: '10px', paddingRight: '10px', }}>
<Icon type="mail" color="white" style={{ fontSize: "30px" }} />
</Badge>
<Select defaultValue="ch" style={{ width: 120, paddingLeft: '30px', paddingRight: '10px' }}>
<Option value="ch">中文</Option>
<Option value="us">English</Option>
</Select>
</div>
</div>
</Header>
<Layout style={{ height: '800px', width: '100%' }}>
<Sider collapsible trigger={null} style={{ background: '#fff' }}
width={400}>
<SidebarConst />
</Sider>
<Layout style={{ padding: '0 24px 24px' }}>
<Breadcrumb style={{ margin: '16px 0' }}>
<Breadcrumb.Item><a href="#">Home</a></Breadcrumb.Item>
<Breadcrumb.Item><a href="#">Dashboard</a></Breadcrumb.Item>
<Breadcrumb.Item>Authentication Summary</Breadcrumb.Item>
</Breadcrumb>
<Content style={{ background: "white" }}>
<br /><br /><br />
<div>这里是content区域</div>
<ContentRouter />
</Content>
</Layout>
</Layout>
<Footer style={{ textAlign: 'center' }}>HAN ©2018 Created by HAM TEAM</Footer>
</Layout>
</div>
</div>
</Router>
);
}
}
export default Index;
左侧导航栏配置如下(修改之后的代码,修改之前的代码是在render中包裹了一层Router,这种写法是错误的)
import React, { Component } from 'react';
import SidebarMenu from '../../components/sidebar/SidebarMenu'
const menus=[
{
title: "Dashboard",
icon: "home",
key: "/home",
subs:[]
},
{
title: "Authentication",
icon: "laptop",
key: "/authentication",
subs: [
{ title: "NAS Clients", key: "/authentication/nas-client", icon: "" },
{ title: "Access Policy", key: "/authentication/access-policy", icon: "" },
{ title: "Authentication Strategy", key: "/authentication/authentication-strategy" },
{ title: "Authentication Record", key: "/authentication/authentication-record" },
{ title: "Captive Portal Access Record", key: "/authentication/captive-portal-record" }
]
},
{
title: "External Server",
icon: "laptop",
key: "/external-server",
subs: [
{ title: "Attribute for LDAP", key: "/external-server/ldap-attribute", icon: "" },
{ title: "Role Mapping for LDAP/AD", key: "/external-server/ldap-role-mapping", icon: "" },
{ title: "LDAP/AD Configuration", key: "/external-server/ldap-configuration" },
{ title: "External Radius", key: "/external-server/external-radius" },
{ title: "LDAP/AD Attribute Dictionary", key: "/external-server/ldap-dictionary" },
{ title: "Radius Attribute Dictionary", key: "/external-server/external-dictionary" }
]
},
{
title: "Guest Access",
icon: "laptop",
key: "/guest-access",
subs: [
{ title: "Global Configuration", key: "/guest-access/global-configuration", icon: "" },
{ title: "Guest Access Strategy", key: "/guest-access/guest-strategy", icon: "" },
{ title: "Self-Registration Request", key: "/guest-access/self-registration" },
{ title: "Guest Access Device", key: "/guest-access/guest-device" }
]
},
{
title: "BYOD Access",
icon: "laptop",
key: "/byod-access",
subs: [
{ title: "BYOD Access Strategy", key: "/byod-access/byod-strategy", icon: "" },
{ title: "BYOD Access Device", key: "/byod-access/byod-device", icon: "" }
]
},
{
title: "Setting",
icon: "setting",
key: "/setting",
subs: [
{ title: "Email Server", key: "/setting/email-server", icon: "" },
{ title: "External Log Server", key: "/setting/external-log", icon: "" },
{ title: "Captive Portal Page", key: "/setting/captive-portal-page", icon: "" }
]
},
{
title: "Certificates",
icon: "safety-certificate",
key: "/certificates",
subs: [
{ title: "Radius Server Certificates", key: "/certificates/radius-certificate", icon: "" },
{ title: "Captive Portal Certificates", key: "/certificates/captive-portal-certificate", icon: "" }
]
},
{
title: "Accounts",
icon: "usergroup-add",
key: "/accounts",
subs: [
{ title: "Guest Account", key: "/accounts/guest-account", icon: "" },
{ title: "Guest Operator", key: "/accounts/guest-operator", icon: "" },
{ title: "Employee Account", key: "/accounts/employee-account", icon: "" },
{ title: "Company Property", key: "/accounts/company-property", icon: "" }
]
},
{
title: "Workflow",
icon: "menu",
key: "/workflow",
subs: [
{ title: "BYOD Workflow", key: "/workflow/byod-workflow", icon: "" },
{ title: "Guest Workflow", key: "/workflow/guest-workflow", icon: "" },
{ title: "Employee Workflow", key: "/workflow/employee-workflow", icon: "" }
]
}
]
class SidebarConst extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return (
<SidebarMenu menus={menus}/>
);
}
}
export default SidebarConst;
在这里将菜单作为一个常量定义,而不是写在render中生成,这样在后期扩展的时候,就可以直接在变量中添加。然后把它作为一个props属性传递给子组件。
子组件定义如下(根据menus遍历生成Menu菜单):
import React, { Component } from 'react';
import { Menu, Icon } from 'antd';
import { BrowserRouter as Router, Link } from 'react-router-dom';
//定义左侧功能菜单列表
const { SubMenu } = Menu;
class SidebarMenu extends Component {
rootSubmenuKeys = ['sub1', 'sub2', 'sub4'];
constructor(props) {
super(props);
this.state = {
openKeys: ['sub1'],
};
console.log("shuchu----", props.menus);
}
onOpenChange = openKeys => {
const latestOpenKey = openKeys.find(key => this.state.openKeys.indexOf(key) === -1);
if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
this.setState({ openKeys });
} else {
this.setState({
openKeys: latestOpenKey ? [latestOpenKey] : [],
});
}
};
//遍历生成父菜单
getParentMenu = ({ title, key, icon, subs }) => {
return (
<SubMenu key={key} title={
<span>
<Icon type={icon}></Icon>
<span>{title}</span>
</span>
}>
{
subs.map((item) => {
return item.subs && item.subs.length > 0 ? this.getParentMenu(item) : this.getChildrenMenu(item)
})
}
</SubMenu>
)
}
//遍历生成子菜单
getChildrenMenu = ({ title, key, icon }) => {
return (
<Menu.Item key={key}>
<Link to={key}>
<span><Icon type={icon}></Icon>{title}</span>
</Link>
</Menu.Item>
)
}
render() {
return (
<div style={{ width: '100%' }}>
<Menu
mode="inline"
openKeys={this.state.openKeys}
onOpenChange={this.onOpenChange}
style={{ width: "100%" }}
>
{
this.props.menus.map((item) => {
return item.subs ? this.getParentMenu(item) : this.getChildrenMenu(item)
})
}
</Menu>
</div>
);
}
}
export default SidebarMenu;
在这里之前是在render函数中,return最外层使用了Router,导致出现问题。
下面是Route的配置:
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
/***Dashboard */
import Dashboard from '../../modules/dashboard/Dashboard'
/***Authentication */
import NasClients from '../../modules/authentication/NasClients'
import AccessPolicy from '../../modules/authentication/AccessPolicy'
import AuthenticationRecord from '../../modules/authentication/AuthenticationRecord'
import AuthenticationStrategy from '../../modules/authentication/AuthenticationStrategy'
import CaptivePortalAccessRecord from '../../modules/authentication/CaptivePortalAccessRecord'
/***Accounts */
import GuestAccount from '../../modules/accounts/GuestAccount'
import GuestOperator from '../../modules/accounts/GuestOperator'
import EmployeeAccount from '../../modules/accounts/EmployeeAccount'
import CompanyProperty from '../../modules/accounts/CompanyProperty'
/***BYOD Access */
import ByodDevice from '../../modules/byod-access/ByodDevice'
import ByodStrategy from '../../modules/byod-access/ByodStrategy'
/***Guest Access */
import GuestDevice from '../../modules/guest-access/GuestDevice'
import GlobalConfiguration from '../../modules/guest-access/GlobalConfiguration'
import GuestStrategy from '../../modules/guest-access/GuestStrategy'
import SelfRegistration from '../../modules/guest-access/SelfRegistration'
/***Certificates */
import CaptivePortalCertificate from '../../modules/certificates/CaptivePortalCertificate'
import RadiusCertificate from '../../modules/certificates/RadiusCertificate'
/***External Radius */
import ExternalRadius from '../../modules/external-server/ExternalRadius'
import ExternalDictionary from '../../modules/external-server/ExternalDictionary'
import LdapAttribute from '../../modules/external-server/LdapAttribute'
import LdapConfiguration from '../../modules/external-server/LdapConfiguration'
import LdapRoleMapping from '../../modules/external-server/LdapRoleMapping'
import LdapDictionary from '../../modules/external-server/LdapDictionary'
/***Setting */
import EmailServer from '../../modules/setting/EmailServer'
import ExternalLogServer from '../../modules/setting/ExternalLogServer'
import CaptivePortalPage from '../../modules/setting/CaptivePortalPage'
/***Workflow */
import ByodWorkflow from '../../modules/workflow/ByodWorkflow'
import GuestWorkflow from '../../modules/workflow/GuestWorkflow'
import EmployeeWorkflow from '../../modules/workflow/EmployeeWorkflow'
class ContentRouter extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<div>
<Route exact path="/home" component={Dashboard} />
<Route exact path="/authentication" component={NasClients} />
<Route exact path="/authentication/nas-client" component={NasClients} />
<Route exact path="/authentication/access-policy" component={AccessPolicy} />
<Route exact path="/authentication/authentication-strategy" component={AuthenticationStrategy} />
<Route exact path="/authentication/authentication-record" component={AuthenticationRecord} />
<Route exact path="/authentication/captive-poratal-access-record" component={CaptivePortalAccessRecord} />
<Route exact path="/external-server" component={LdapAttribute} />
<Route exact path="/external-server/ldap-attribute" component={LdapAttribute} />
<Route exact path="/external-server/ldap-role-mapping" component={LdapRoleMapping} />
<Route exact path="/external-server/external-radius" component={ExternalRadius} />
<Route exact path="/external-server/ldap-dictionary" component={LdapDictionary} />
<Route exact path="/external-server/external-dictionary" component={ExternalDictionary} />
<Route exact path="/external-server/ldap-configuration" component={LdapConfiguration} />
<Route exact path="/guest-access" component={GlobalConfiguration} />
<Route exact path="/guest-access/global-configuration" component={GlobalConfiguration} />
<Route exact path="/guest-access/guest-strategy" component={GuestStrategy} />
<Route exact path="/guest-access/self-registration" component={SelfRegistration} />
<Route exact path="/guest-access/guest-device" component={GuestDevice} />
<Route exact path="/byod-access" component={ByodStrategy} />
<Route exact path="/byod-access/byod-strategy" component={ByodStrategy} />
<Route exact path="/byod-access/byod-device" component={ByodDevice} />
<Route exact path="/setting" component={EmailServer} />
<Route exact path="/setting/email-server" component={EmailServer} />
<Route exact path="/setting/external-log" component={ExternalLogServer} />
<Route exact path="/setting/captive-portal-page" component={CaptivePortalPage} />
<Route exact path="/certificates" component={RadiusCertificate} />
<Route exact path="/certificates/radius-certificate" component={RadiusCertificate} />
<Route exact path="/certificates/captive-portal-certificate" component={CaptivePortalCertificate} />
<Route exact path="/accounts" component={GuestAccount} />
<Route exact path="/accounts/guest-account" component={GuestAccount} />
<Route exact path="/accounts/guest-operator" component={GuestOperator} />
<Route exact path="/accounts/employee-account" component={EmployeeAccount} />
<Route exact path="/accounts/company-property" component={CompanyProperty} />
<Route exact path="/workflow" component={ByodWorkflow} />
<Route exact path="/workflow/byod-workflow" component={ByodWorkflow} />
<Route path="/workflow/guest-workflow" component={GuestWorkflow} />
<Route path="/workflow/employee-workflow" component={EmployeeWorkflow} />
</div>
);
}
}
export default ContentRouter;
注意:在使用Link和Route时,最外层只能有一个Router。