antd+react Menu随url切换选中项

本文介绍如何在使用Antd和React时,使Menu组件的选中项根据URL变化而自动切换。在点击按钮跳转页面或刷新时,确保Menu正确显示当前页面对应的菜单项。通过引入withRouter并理解其工作原理,将路由信息传递给菜单组件,解决了刷新后菜单返回默认状态的问题,特别是对于包含二级菜单的情况,保证URL与菜单键的一致性,实现完美同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:
1、当点击页面中的按钮切换到另一个页面时,menu选中项并没有跟着改变;
2、刷新页面时,url保持不变,content不变,但是menu会回到默认设置。

参考:antd中menu选中状态没有跟上路由[解决]

参考了大佬的方法,终于实现了!!!

先看一下withRouter的解释:react withRouter

代码实现

与大佬的方法不同点在于:
1、路由与菜单不再一个组件中写,所以history通过属性的方式传递

// routes/index.js
const IRouter = withRouter(({ history }) => {
    return (
        // <withRouter>  最外层的withRouter去掉,不然会报警告
            <HashRouter>
                <Route path="/login" component={Login}></Route>
                <ILayout history={history}>    //=>将history传到实现菜单的组件中
                    <Switch>
                        <Route exact path="/" component={OrderList}></Route>
                        <Route path="/order/list" component={OrderList}></Route>
                        <Route path="/order/add" component={AddOrder}></Route>
                        <Route path="/user/list" component={UserList}></Route>
                        <Route path="/user/add" component={AddUser}></Route>
                        <Route path="/department/list" component={DepartmentList}></Route>
                        <Route path="/department/add" component={AddDepartment}></Route>
                        <Route path="/job/list" component={JobList}></Route>
                        <Route path="/job/add" component={AddJob}></Route>
                    </Switch>
                </ILayout>
            </HashRouter>
        // </withRouter>
    );
        
})

export default IRouter;

2、菜单是二级菜单,根据url判断打开的是哪个一级菜单的,避免刷新页面后打开菜单变成默认的(注:url与菜单的key保持一致

// pages/layout.js
export default class ILayout extends React.Component {
    // ...
    render() {
        const { collapsed} = this.state;
        let pathname = this.props.history.location.pathname;  //=>获取当前url
        //=>用于根据url设置打开的一级菜单是哪个  
        const defaultOpenKeys = pathname !== '/' ? [/\/(\w+)/.exec(pathname)[0]] : ['/order']; 
        pathname = pathname !== '/' ? pathname : '/order/list'; //=>避免第一次进入页面时没有选中项    
        return (
            <Layout>
                <Sider trigger={null} collapsible collapsed={collapsed} >
                    <div className="logo" />
                    <Menu theme="dark" mode="inline"
                        defaultOpenKeys={defaultOpenKeys}
                        selectedKeys={[pathname]}
                    >
                        {this.state.menuList}
                    </Menu>
                </Sider>
                <Layout className="site-layout">
                    <Header className="site-layout-background" style={{ padding: 0 }}>
                    </Header>
                    <Content className="site-layout-background"
                        changeMenu={this.changeMenu}
                        style={{
                            margin: '24px 16px',
                            padding: 24,
                            minHeight: 280,
                        }}
                    >
                        {this.props.children}
                    </Content>
                </Layout>
            </Layout>
        );
    }
}

最后,与大佬一样,在入口文件index.js中:

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import '@/reset.css';
import 'antd/dist/antd.css';
import IRouter from '@/routes';
import {HashRouter, Route} from 'react-router-dom';

const Root = () => {
    return (
        <HashRouter basename='/'>
            <Route path={``} component={IRouter} />
        </HashRouter>
    )
}

ReactDOM.render(
    <Root />,
  document.getElementById('root')
);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值