Next.js中使用Chakra UI菜单组件出现布局异常问题求助
问题描述
作为React和Next.js新手,在使用Chakra UI的Menu组件时出现布局异常、样式丑陋的问题:
- 当前布局:

- 期望布局:

相关代码如下:
Navbar.jsx
import Link from 'next/link'; import { Menu, MenuButton, MenuList, MenuItem, IconButton, Flex, Box, Spacer, MenuGroup } from '@chakra-ui/react'; import { FcMenu, FcHome, FcAbout } from 'react-icons/fc'; import { BsSearch } from 'react-icons/bs'; import { FiKey } from 'react-icons/fi'; const Navbar =()=>( <Flex p='2' borderBottom='1px' borderColor='black.1000'> <Box fontSize="3xl" color="black.300" fontWeight="bold"> <Link href='/' paddingLeft='5'>Testing Name</Link> </Box> <Spacer/> <Box> <Menu isLazy colorScheme="black"> <MenuButton as={IconButton} rightIcon={<FcMenu></FcMenu>} color='black'>Menu Item</MenuButton> <MenuList> <Link href='/'> <MenuItem icon={<FcHome/>}>Home</MenuItem> </Link> <Link href='/discussion/all' > <MenuItem icon={<FcAbout/>}>Discussion</MenuItem> </Link> <MenuGroup title='venue'> <Link href='/venue/search' passHref> <MenuItem icon={<BsSearch/>}>Search</MenuItem> </Link> <Link href='/venue/search?purpose=for-sale' passHref> <MenuItem icon={<FcAbout/>}>buy property</MenuItem> </Link> <Link href='/venue/search?purpose=for-rent' passHref> <MenuItem icon={<FiKey/>}>rent property</MenuItem> </Link> </MenuGroup> </MenuList> </Menu> </Box> </Flex> ) export default Navbar;
Layout.js
import Head from 'next/head'; import { Box } from '@chakra-ui/react'; import Navbar from './Navbar'; export default function Layout({ children }) { return ( <> <Head> <title>Testing app</title> </Head> <Box maxWidth='1280px' m='auto'> <header> <Navbar /> </header> <main>{children}</main> </Box> </> ); }
_app.js
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react'; import theme from '../styles/theme'; import '../styles/globals.css'; import CommonLayout from '../components/Layout'; function MyApp({ Component, pageProps }) { return ( <ChakraProvider resetCSS={false}> <ColorModeScript initialColorMode={theme.config.initialColorMode}/> <CommonLayout> <Component {...pageProps} /> </CommonLayout> </ChakraProvider> ); } export default MyApp;
theme.js
// theme.js // 1. import `extendTheme` function import { extendTheme } from '@chakra-ui/react' // 2. Add your color mode config const config = { initialColorMode: 'light', useSystemColorMode: false, } // 3. extend the theme(which I just directly copy from chakra ui documentation) const theme = extendTheme({ config }) export default theme
解决方案
1. 启用Chakra UI的CSS重置
ChakraProvider的resetCSS设为false会丢失默认样式,导致与全局样式冲突,需改为true:
修改_app.js:
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react'; import theme from '../styles/theme'; import '../styles/globals.css'; import CommonLayout from '../components/Layout'; function MyApp({ Component, pageProps }) { return ( <ChakraProvider resetCSS={true}> <ColorModeScript initialColorMode={theme.config.initialColorMode}/> <CommonLayout> <Component {...pageProps} /> </CommonLayout> </ChakraProvider> ); } export default MyApp;
2. 修正Next.js Link与MenuItem的嵌套方式
原写法中Link包裹MenuItem会破坏Chakra的样式继承,正确做法是用MenuItem的as属性指定为Link:
修改Navbar.jsx中的MenuList部分:
<MenuList> <MenuItem as={Link} href='/' icon={<FcHome/>}>Home</MenuItem> <MenuItem as={Link} href='/discussion/all' icon={<FcAbout/>}>Discussion</MenuItem> <MenuGroup title='venue'> <MenuItem as={Link} href='/venue/search' icon={<BsSearch/>}>Search</MenuItem> <MenuItem as={Link} href='/venue/search?purpose=for-sale' icon={<FcAbout/>}>buy property</MenuItem> <MenuItem as={Link} href='/venue/search?purpose=for-rent' icon={<FiKey/>}>rent property</MenuItem> </MenuGroup> </MenuList>
3. 优化MenuButton样式(可选)
若要让按钮更贴合期望样式,可添加variant和size属性调整:
<MenuButton as={IconButton} rightIcon={<FcMenu />} color='black' variant="outline" size="md">Menu</MenuButton>
4. 排查全局样式冲突
检查globals.css中是否存在覆盖Chakra默认样式的规则,如有冲突需调整或移除相关代码。
内容的提问来源于stack exchange,提问作者lok cheng
相关产品推荐
相关产品推荐

