Link和Route扥开配置时,url发生变化时,组件没有重新加载的问题

在使用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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值