React RMWC:useState控制TopAppBar与Drawer状态异常问题
问题解决:RMWC TopAppBar控制Drawer时汉堡菜单状态异常
问题分析
点击TopAppBar的汉堡菜单时,按钮始终处于激活状态,Drawer未同步切换;控制台中isNavOpen值正常变更,但使用普通布尔值时按钮状态显示正常。核心原因是SimpleTopAppBar的navigationIcon默认由内部管理激活状态,未与外部的isNavOpen状态绑定,导致按钮无法感知Drawer的开关状态。
解决方案
- 给
SimpleTopAppBar的navigationIcon传递activated属性,绑定isNavOpen,让按钮状态与Drawer显示状态同步 - 使用函数式更新
setIsNavOpen(prev => !prev),避免React状态更新的闭包问题(原代码中console.log(isNavOpen)输出的是更新前的旧值,函数式更新可确保拿到最新状态)
修正后的代码
import { useState } from "react"; import { SimpleTopAppBar } from "@rmwc/top-app-bar"; import "@rmwc/top-app-bar/styles"; import "@rmwc/icon/styles"; import "@rmwc/drawer/styles"; import "@rmwc/list/styles"; import { Drawer, DrawerContent } from "@rmwc/drawer"; import { List, SimpleListItem } from "@rmwc/list"; function App() { const [isNavOpen, setIsNavOpen] = useState(false); return ( <> <SimpleTopAppBar title="Test menu list" navigationIcon={{ activated: isNavOpen, // 绑定按钮激活状态到Drawer的开关状态 onClick: () => setIsNavOpen(prev => !prev) }} actionItems={[ { icon: "file_download", onClick: () => console.log("Do Something"), }, { icon: "login", onClick: () => console.log("Do Something") }, ]} /> <Drawer open={isNavOpen}> <DrawerContent> <List twoLine> <SimpleListItem graphic="star_border" text="Cookies" secondaryText="Chocolate chip" metaIcon="info" /> <SimpleListItem graphic="local_pizza" text="Pizza" secondaryText="Pepperoni" metaIcon="info" /> <SimpleListItem activated graphic="mood" text="Icecream" secondaryText="Chocolate cookie dough" meta="Winner!" /> </List> </DrawerContent> </Drawer> </> ); } export default App;
也可以直接传递组件形式的navigationIcon:
navigationIcon={<SimpleTopAppBarNavigationIcon activated={isNavOpen} onClick={() => setIsNavOpen(prev => !prev)} />}
关键说明
- RMWC组件大多支持受控模式,当用外部状态控制组件行为时,需显式传递状态给对应属性,不能仅依赖事件回调
- 函数式更新
setIsNavOpen(prev => !prev)可确保每次基于最新状态值切换,避免异步更新导致的逻辑偏差
内容的提问来源于stack exchange,提问作者Marcin
相关产品推荐
相关产品推荐

