React+ChakraUI中点击Links组件时Drawer的onClose失效问题
问题描述
使用HorizonUI模板结合ChakraUI与ReactJS开发,给Navbar组件添加了Drawer,在Drawer主体中调用Links组件。目前点击关闭按钮或Drawer外部可正常关闭Drawer,但点击Links组件内的导航链接时,无法触发onClose关闭Drawer。
当前Drawer中Links组件的调用代码:
<Links routes={routes} onClick={onClose}/>
Navbar.js 代码
import Links from "components/sidebar/components/Links"; export default function AdminNavbar(props) { const { isOpen, onOpen, onClose } = useDisclosure() const { secondary, brandText } = props; let mainText = useColorModeValue('navy.700', 'white'); let navbarPosition = 'fixed'; let navbarFilter = 'none'; let navbarBackdrop = 'blur(20px)'; let navbarShadow = 'none'; let navbarBg = useColorModeValue('rgba(244, 247, 254, 0.2)', 'rgba(11,20,55,0.5)'); let navbarBorder = 'transparent'; let secondaryMargin = '0px'; let gap = '0px'; return ( <Box position={navbarPosition} boxShadow={navbarShadow} bg={navbarBg} borderColor={navbarBorder} filter={navbarFilter} backdropFilter={navbarBackdrop} backgroundPosition='center' backgroundSize='cover' borderRadius='16px' alignItems={{ xl: 'center' }} display={secondary ? 'block' : 'flex'} minH='50px' justifyContent={{ xl: 'center' }} lineHeight='25.6px' mx='auto' mt={secondaryMargin} top={{ base: '12px', md: '16px', lg: '20px', xl: '20px' }} right={{ base: '500px' }} left={{ base: '500px' }} onClick={onOpen} > <Flex alignItems={{ xl: 'center' }} mb={gap} > <Box> <Text color={mainText} href='#' bg='inherit' borderRadius='inherit' fontWeight='bold' fontSize='34px' _hover={{ color: { mainText } }} _active={{ bg: 'inherit', transform: 'none', borderColor: 'transparent' }} _focus={{ boxShadow: 'none' }} style={{ userSelect: "none" }}> {brandText} </Text> </Box> </Flex> <Drawer placement="top" isOpen={isOpen} onClose={onClose} size='xs' blockScrollOnMount={false}> <DrawerOverlay /> <DrawerContent boxShadow={navbarShadow} bg={navbarBg} borderColor={navbarBorder} filter={navbarFilter} backdropFilter={navbarBackdrop} backgroundPosition='center' backgroundSize='cover' borderRadius='16px' alignItems={{ xl: 'center' }} justifyContent={{ xl: 'center' }} lineHeight='25.6px' mx='auto' > <DrawerCloseButton /> <DrawerHeader color={mainText} href='#' fontWeight='bold' fontSize='40px' style={{ userSelect: "none" }} onClick={onClose}> Inventory SCM </DrawerHeader> <DrawerBody> <Links routes={routes} onClick={onClose}/> </DrawerBody> </DrawerContent> </Drawer> </Box> ); }
Links.js 代码
export function SidebarLinks(props) { let location = useLocation(); let activeColor = useColorModeValue("gray.700", "white"); let inactiveColor = useColorModeValue( "secondaryGray.600", "secondaryGray.600" ); let activeIcon = useColorModeValue("brand.500", "white"); let textColor = useColorModeValue("secondaryGray.500", "white"); let brandColor = useColorModeValue("brand.500", "brand.400"); const { routes } = props; const activeRoute = (routeName) => { return location.pathname.includes(routeName); }; const createLinks = (routes) => { return routes.map((route, index) => { if (route.category) { return ( <> <Text fontSize={"md"} color={activeColor} fontWeight='bold' mx='auto' ps={{ sm: "10px", xl: "16px", }} pt='18px' pb='12px' key={index}> {route.name} </Text> {createLinks(route.items)} </> ); } else if ( route.layout === "/admin" || route.layout === "/auth" || route.layout === "/rtl" ) { return ( <NavLink key={index} to={route.layout + route.path}> {route.icon ? ( <Box> <HStack spacing={ activeRoute(route.path.toLowerCase()) ? "22px" : "26px" } py='5px' ps='10px'> <Flex w='100%' alignItems='center' justifyContent='center'> <Box color={ activeRoute(route.path.toLowerCase()) ? activeIcon : textColor } me='18px'> {route.icon} </Box> <Text me='auto' color={ activeRoute(route.path.toLowerCase()) ? activeColor : textColor } fontWeight={ activeRoute(route.path.toLowerCase()) ? "bold" : "normal" }> {route.name} </Text> </Flex> <Box h='36px' w='4px' bg={ activeRoute(route.path.toLowerCase()) ? brandColor : "transparent" } borderRadius='5px' /> </HStack> </Box> ) : ( <Box> <HStack spacing={ activeRoute(route.path.toLowerCase()) ? "22px" : "26px" } py='5px' ps='10px'> <Text me='auto' color={ activeRoute(route.path.toLowerCase()) ? activeColor : inactiveColor } fontWeight={ activeRoute(route.path.toLowerCase()) ? "bold" : "normal" }> {route.name} </Text> <Box h='36px' w='4px' bg='brand.400' borderRadius='5px' /> </HStack> </Box> )} </NavLink> ); } }); }; return createLinks(routes); } export default SidebarLinks;
解决方案
问题核心是Links组件没有接收并传递onClick属性到内部的NavLink元素上。修改Links组件,让它接收onClick参数并绑定到每个导航链接即可:
修改后的Links.js代码:
export function SidebarLinks(props) { let location = useLocation(); let activeColor = useColorModeValue("gray.700", "white"); let inactiveColor = useColorModeValue( "secondaryGray.600", "secondaryGray.600" ); let activeIcon = useColorModeValue("brand.500", "white"); let textColor = useColorModeValue("secondaryGray.500", "white"); let brandColor = useColorModeValue("brand.500", "brand.400"); // 从props中解构出onClick const { routes, onClick } = props; const activeRoute = (routeName) => { return location.pathname.includes(routeName); }; const createLinks = (routes) => { return routes.map((route, index) => { if (route.category) { return ( <> <Text fontSize={"md"} color={activeColor} fontWeight='bold' mx='auto' ps={{ sm: "10px", xl: "16px", }} pt='18px' pb='12px' key={index}> {route.name} </Text> {createLinks(route.items)} </> ); } else if ( route.layout === "/admin" || route.layout === "/auth" || route.layout === "/rtl" ) { return ( // 在NavLink上绑定onClick事件,触发传入的onClose方法 <NavLink key={index} to={route.layout + route.path} onClick={onClick}> {route.icon ? ( <Box> <HStack spacing={ activeRoute(route.path.toLowerCase()) ? "22px" : "26px" } py='5px' ps='10px'> <Flex w='100%' alignItems='center' justifyContent='center'> <Box color={ activeRoute(route.path.toLowerCase()) ? activeIcon : textColor } me='18px'> {route.icon} </Box> <Text me='auto' color={ activeRoute(route.path.toLowerCase()) ? activeColor : textColor } fontWeight={ activeRoute(route.path.toLowerCase()) ? "bold" : "normal" }> {route.name} </Text> </Flex> <Box h='36px' w='4px' bg={ activeRoute(route.path.toLowerCase()) ? brandColor : "transparent" } borderRadius='5px' /> </HStack> </Box> ) : ( <Box> <HStack spacing={ activeRoute(route.path.toLowerCase()) ? "22px" : "26px" } py='5px' ps='10px'> <Text me='auto' color={ activeRoute(route.path.toLowerCase()) ? activeColor : inactiveColor } fontWeight={ activeRoute(route.path.toLowerCase()) ? "bold" : "normal" }> {route.name} </Text> <Box h='36px' w='4px' bg='brand.400' borderRadius='5px' /> </HStack> </Box> )} </NavLink> ); } }); }; return createLinks(routes); } export default SidebarLinks;
主要修改点:
- 从
props中解构出onClick参数:const { routes, onClick } = props; - 在每个
NavLink元素上添加onClick={onClick},点击导航链接时会同时触发页面跳转和Drawer关闭操作。
内容的提问来源于stack exchange,提问作者Ken Arya
相关产品推荐
相关产品推荐

