调整屏幕尺寸时保留Sidebar组件内已选中选项的状态
问题根因
响应式切换侧边栏展示形态时,你大概率是通过条件渲染直接卸载了当前形态的FiltersSideBar组件,再重新挂载另一形态的同组件。React组件卸载时,Filter1、Filter2等子组件内部维护的本地状态会被全部清空,重挂载时就会回到初始状态。
这也能解释你观察到的现象:筛选规则本身是存在父组件/全局状态中的,不会随侧边栏组件卸载被清除,所以逻辑依然生效;但筛选控件的UI选中状态存在子组件本地,组件重建后状态丢失,就显示为未选中的空状态。
修复方案
你可以二选一实现:
- 方案一(推荐,适配性最好):将所有筛选控件的交互状态上提到
FiltersSideBar的父组件,或项目已用的全局状态层统一维护,不要在Filter1/Filter2组件内部存选中状态。不管侧边栏是常驻态还是浮层态,都传入同一份状态源做渲染,组件重挂载时直接读取已有状态,就不会重置。
参考改造代码:
父组件部分:// 统一维护筛选状态 const [filter1Selected, setFilter1Selected] = useState([]); const [filter2Selected, setFilter2Selected] = useState([]); const [mobileDrawerOpen, setMobileDrawerOpen] = useState(false); // 两种形态共用同一个FiltersSideBar组件的状态源 return ( <> {/* 大屏常驻侧边栏 */} {window.innerWidth >= 600 && ( <FiltersSideBar className="permanent-sidebar" filter1Value={filter1Selected} onFilter1Change={setFilter1Selected} filter2Value={filter2Selected} onFilter2Change={setFilter2Selected} /> )} {/* 小屏浮层侧边栏 */} {window.innerWidth < 600 && ( <> <button onClick={() => setMobileDrawerOpen(true)}> <ArrowBackIosNewIcon /> </button> <Drawer open={mobileDrawerOpen} onClose={() => setMobileDrawerOpen(false)}> <FiltersSideBar className="drawer-sidebar" filter1Value={filter1Selected} onFilter1Change={setFilter1Selected} filter2Value={filter2Selected} onFilter2Change={setFilter2Selected} /> </Drawer> </> )} </> )FiltersSideBar组件改造:export default function FiltersSideBar(props) { const { className, filter1Value, onFilter1Change, filter2Value, onFilter2Change } = props; return ( <CardContent className={className}> <Table> <TableBody> <TableRow> <TableCell> <Filter1 value={filter1Value} onChange={onFilter1Change} /> </TableCell> </TableRow> <TableRow> <TableCell> <Filter2 value={filter2Value} onChange={onFilter2Change} /> </TableCell> </TableRow> </TableBody> </Table> </CardContent> ); } - 方案二(改造成本低):取消条件渲染的逻辑,全程只挂载一次
FiltersSideBar组件,通过CSS媒体查询控制不同宽度下的组件样式:宽度≥600px时用静态定位常驻左侧;宽度<600px时默认隐藏,点击唤出按钮时切换class让组件以fixed定位浮在页面上层,搭配遮罩层实现抽屉效果。组件全程不卸载,内部状态自然不会丢失。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

