Antd 使用Layout布局刷新会导致左侧栏闪动,怎么解决
这是正常时的画面
<Layout style={{ minHeight: '100vh' }} className={style.container}>
<Sider style={{ background: '#545c65' }} collapsible collapsed={collapsed} trigger={null}>
<p className='bigTitle'>{collapsed ? '后台' : '通用后台管理系统'}</p>
<Menu
theme="dark"
defaultSelectedKeys={[location.pathname.slice(1)]}
mode="inline"
items={items}
style={{ background: '#545c65' }}
onClick={(item) => clickMenu(item)}
/>
</Sider>
</Layout>
只要定义了Menu标签的items这个属性,就会出现这样的问题
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题可能是由于在组件的重新渲染过程中,导致Sider组件重新挂载,从而导致左侧栏闪动。可以尝试以下两种方式解决:
import React, { memo } from 'react';
const MySider = memo(({ items, handleClick }) => {
return (
<Layout style={{ minHeight: '100vh' }} className={style.container}>
<Sider style={{ background: '#545c65' }} collapsible collapsed={collapsed} trigger={null}>
<p className='bigTitle'>{collapsed ? '后台' : '通用后台管理系统'}</p>
<Menu
theme="dark"
defaultSelectedKeys={[location.pathname.slice(1)]}
mode="inline"
items={items}
style={{ background: '#545c65' }}
onClick={(item) => handleClick(item)}
/>
</Sider>
</Layout>
)
})
export default MySider;
在使用这个组件的父组件中,可以把items和handleClick封装为函数,在渲染的时候传递给MySider组件:
import React, { useCallback } from 'react';
function MyPage() {
const items = [...];
const handleClick = useCallback((item) => {...}, []);
return (
<div>
<MySider items={items} handleClick={handleClick} />
<div>...</div>
</div>
)
}
这样可以确保在父组件的状态或者函数不发生变化的情况下,MySider组件不会重新渲染。
import React from 'react';
function MySider({ items, handleClick }) {
return (
<Layout style={{ minHeight: '100vh' }} className={style.container}>
<Sider style={{ background: '#545c65' }} collapsible collapsed={collapsed} trigger={null}>
<p className='bigTitle'>{collapsed ? '后台' : '通用后台管理系统'}</p>
<Menu
key={items.length} // 添加一个key值
theme="dark"
defaultSelectedKeys={[location.pathname.slice(1)]}
mode="inline"
items={items}
style={{ background: '#545c65' }}
onClick={(item) => handleClick(item)}
/>
</Sider>
</Layout>
)
}
export default MySider;
这样,每当items数组发生变化时,就会重新渲染整个MySider组件,但其他组件不会受到影响。
如果我的回答解决了您的问题,请采纳!
import React, { useState, useCallback, useLayoutEffect } from 'react';
import { Layout, Menu } from 'antd';
const { Sider } = Layout;
const { SubMenu } = Menu;
const MyLayout = () => {
const [collapsed, setCollapsed] = useState(false);
// 切换菜单栏是否收缩
const toggle = useCallback(() => {
setCollapsed(!collapsed);
}, [collapsed]);
// 点击菜单项
const handleClickMenu = useCallback(() => {
// do something
}, []);
useLayoutEffect(() => {
// 修改侧边栏宽度,解决刷新页面时的缩进问题
const sider = document.querySelector('.ant-layout-sider') as HTMLElement;
if (sider) {
sider.style.width = collapsed ? '80px' : '200px';
}
}, [collapsed]);
const menu = (
<Menu
theme="dark"
mode="inline"
onClick={handleClickMenu}
>
<SubMenu key="sub1" title="Option 1">
<Menu.Item key="1">Option 1.1</Menu.Item>
<Menu.Item key="2">Option 1.2</Menu.Item>
</SubMenu>
<SubMenu key="sub2" title="Option 2">
<Menu.Item key="3">Option 2.1</Menu.Item>
<Menu.Item key="4">Option 2.2</Menu.Item>
</SubMenu>
</Menu>
);
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider
style={{ background: '#545c65', collapsedWidth: 0 }}
collapsible
collapsed={collapsed}
onCollapse={toggle}
trigger={null}
>
<div className="logo" />
{menu}
</Sider>
<Layout>
<div>Content</div>
</Layout>
</Layout>
);
};
引用chatGPT作答,这种闪动可能是因为Antd的Layout组件的默认样式不支持内容高度的变化,导致在刷新页面布局时会出现闪烁的问题。解决这个问题的一种方法是使用CSS样式来覆盖默认的Layout组件样式,以适应内容高度的变化。以下是可能的解决方法:
1.在Layout组件上设置style属性为minHeight: "100vh",以确保Layout组件占满整个视口高度,并且在内容高度变化时不会导致整个布局的变化。
2.在Sider组件上设置style属性为height: "100%",以确保Sider组件占满Layout组件的高度,并且在内容高度变化时不会导致整个布局的变化。
3.在Menu组件上设置style属性为height: "100%",以确保Menu组件占满Sider组件的高度,并且在内容高度变化时不会导致整个布局的变化。
使用下面的代码,可以解决问题:
<Layout style={{ minHeight: '100vh' }} className={style.container}>
<Sider style={{ background: '#545c65', height: '100%' }} collapsible collapsed={collapsed} trigger={null}>
<p className='bigTitle'>{collapsed ? '后台' : '通用后台管理系统'}</p>
<Menu
theme="dark"
defaultSelectedKeys={[location.pathname.slice(1)]}
mode="inline"
items={items}
style={{ background: '#545c65', height: '100%' }}
onClick={(item) => clickMenu(item)}
/>
</Sider>
</Layout>
不知道你这个问题是否已经解决, 如果还没有解决的话:我没有使用过 Antd 的 Layout 布局,无法对该问题进行解答。建议您查阅 Antd 官方文档中的相关内容,或搜索社区中是否有其他开发者遇到过类似问题并提供了解决方案。